问:
SQl query for overlap of users in different stream service?
I'm new to sql and keen to learn but i'm having trouble with this problem. I would appreciate any help. I have a login table with following column and i have explained the columns below.

```<code>    id  cur_date    user_id stream  user_signup tot_sec mov_sec ser_sec
    1   19-MAY-20   5right  TV      12-MAY-20   73430   73430   0
    2   19-MAY-20   5right  TV      12-JAN-16   3430    3430    0
    3   19-MAY-20   5left   MOBILE  03-JAN-20   3457    3430    45
    4   19-MAY-20   7left   MOBILE  04-JAN-20   4980    100     4880
    5   19-MAY-20   7right  Tv      04-FEB-20   15731   0       15731
    6   19-MAY-20   7right  WEB     04-APR-20   16731   1000    15731
    7   19-MAY-20   7left   TV      04-MAR-20   2731    1000    1731
    8   19-MAY-20   5left   TV      03-APR-20   12731   11000   1731

cur_date is when we take the user metrics
user_id (have same id on different stream service)
user_signup (user sign up date)
stream( streaming ways, contains 3 values mobile, web, TV)
tot_sec (total active time seconds)
mov_sec (watching movie time in seconds)
ser_sec(watching tv series time in seconds)
</code>```

Quesion: write the SQL to which two stream have the greatest overlap of users? The users have the same id across stream service?

I wrote this:

```<code> select r1.user_id, r1.stream
from login as r1
inner join login as r2
on r1.user_id = r2.user_id
order by r1.stream;
</code>```

However this is not quite what im asking for. Any ideas?

Thanks!

答:
Hmmm . . . If you mean the counts of logged in users, then you need some sort of aggregation to count.  So:

```<code>select s1.stream, s2.stream, count(*)
from login s1 join
     login s2
     on s1.user_id = s2.user_id and s1.stream <> s2.stream
group by s1.stream, s2.stream
order by count(*) desc
fetch first 1 row only;
</code>```

If the users can be repeated for a given stream, then you want count(distinct s1.user_id) instead of count(*).

Body:
I'm new to sql and keen to learn but i'm having trouble with this problem. I would appreciate any help. I have a login table with following column and i have explained the columns below.

    id  cur_date    user_id stream  user_signup tot_sec mov_sec ser_sec
    1   19-MAY-20   5right  TV      12-MAY-20   73430   73430   0
    2   19-MAY-20   5right  TV      12-JAN-16   3430    3430    0
    3   19-MAY-20   5left   MOBILE  03-JAN-20   3457    3430    45
    4   19-MAY-20   7left   MOBILE  04-JAN-20   4980    100     4880
    5   19-MAY-20   7right  Tv      04-FEB-20   15731   0       15731
    6   19-MAY-20   7right  WEB     04-APR-20   16731   1000    15731
    7   19-MAY-20   7left   TV      04-MAR-20   2731    1000    1731
    8   19-MAY-20   5left   TV      03-APR-20   12731   11000   1731

cur_date is when we take the user metrics
user_id (have same id on different stream service)
user_signup (user sign up date)
stream( streaming ways, contains 3 values mobile, web, TV)
tot_sec (total active time seconds)
mov_sec (watching movie time in seconds)
ser_sec(watching tv series time in seconds)

Quesion: write the SQL to which two stream have the greatest overlap of users? The users have the same id across stream service?

I wrote this:

 select r1.user_id, r1.stream
from login as r1
inner join login as r2
on r1.user_id = r2.user_id
order by r1.stream;

However this is not quite what im asking for. Any ideas?

Thanks!

Body:
Hmmm . . . If you mean the counts of logged in users, then you need some sort of aggregation to count.  So:

select s1.stream, s2.stream, count(*)
from login s1 join
     login s2
     on s1.user_id = s2.user_id and s1.stream <> s2.stream
group by s1.stream, s2.stream
order by count(*) desc
fetch first 1 row only;

If the users can be repeated for a given stream, then you want count(distinct s1.user_id) instead of count(*).


来源: stackexchange

问:
Plotly lines using start and end dates
I have a DataFrame with the columns: start date, end date, and value. How can I plot one line for each start-end date in Plotly?

Example:

```<code>import pandas as pd
import plotly.express as px
df = pd.DataFrame({"start date": [1,2,3,4], "end date":[8,7,4,9], "value":[11,3,11,4]})
fig = px.line(df, x=["start date","end date"], y="value")
fig.show()
</code>```

In this case, there are only two lines for the columns start date and end date. However, what I'm looking for is 1 line for each start-end date. I tried with the parameter color="value" but, in value 11 it only plots 1 line. I could print it with simple plot of plt as:

```<code>import matplotlib.pyplot as plt
x = [df["start date"], df["end date"]]
y = [df["value"], df["value"]]
plt.plot(x, y)
plt.show()
</code>```

答:
To create multiple 'indepent' lines, you'll have to create several traces, like in the example below:

```<code>import pandas as pd
import plotly.graph_objs as go

df = pd.DataFrame({"start date": [1,2,3,4], "end date":[8,7,4,9], "value":[11,3,11,4]})

fig = go.Figure()
for (start, end, value) in zip(df["start date"], df["end date"], df["value"]):
    name = f"{start} to {end}"
    fig.add_trace(go.Scatter(x=[start, end], y=[value, value],
                    mode='lines', name = name))

fig.show()
</code>```

The result is:

ContentLicense: CC BY-SA 4.0

Title: Plotly lines using start and end dates

Body:
I have a DataFrame with the columns: start date, end date, and value. How can I plot one line for each start-end date in Plotly?

Example:

import pandas as pd
import plotly.express as px
df = pd.DataFrame({"start date": [1,2,3,4], "end date":[8,7,4,9], "value":[11,3,11,4]})
fig = px.line(df, x=["start date","end date"], y="value")
fig.show()

In this case, there are only two lines for the columns start date and end date. However, what I'm looking for is 1 line for each start-end date. I tried with the parameter color="value" but, in value 11 it only plots 1 line. I could print it with simple plot of plt as:

import matplotlib.pyplot as plt
x = [df["start date"], df["end date"]]
y = [df["value"], df["value"]]
plt.plot(x, y)
plt.show()

Body:
To create multiple 'indepent' lines, you'll have to create several traces, like in the example below:

import pandas as pd
import plotly.graph_objs as go

df = pd.DataFrame({"start date": [1,2,3,4], "end date":[8,7,4,9], "value":[11,3,11,4]})

fig = go.Figure()
for (start, end, value) in zip(df["start date"], df["end date"], df["value"]):
    name = f"{start} to {end}"
    fig.add_trace(go.Scatter(x=[start, end], y=[value, value],
                    mode='lines', name = name))

fig.show()

The result is:


问:
Reload the page just once if a div is above certain position
I want to reload the page only once if a given div is positioned higher than position:absolute; top:15%.

I think this could be done with jQuery's .css method, something like:

```<code>if ('#mydive').css('top') > '15%' {
    //reload the page
}
</code>```

Could someone suggest a simple solution, preferably jQuery or pure JavaScript?

答: Well, it is rather hard to say how you should determine the position of the div since you presented no code, but basically you should write a function that fetches the window height and the offset of the div relative to the top of the window to determine whether it is higher than 15%. You then need to call this function every time using the window.onscroll event listener. When the function returns true, trigger trigger window.location.reload(true) to reload the page. I imagine this could be done fairly easily in jQuery as well.</p>

ContentLicense: CC BY-SA 3.0

Body:
I want to reload the page only once if a given div is positioned higher than position:absolute; top:15%.

I think this could be done with jQuery's .css method, something like:

if ('#mydive').css('top') > '15%' {
    //reload the page
}

Could someone suggest a simple solution, preferably jQuery or pure JavaScript?


问:
How to connect between Firebase authentication and Firebase collection database?
So I'm trying to understand how Firebase works. I'm using Firebase cloud for the Database. I have created a collection like this:

```<code>'groups': {
     'some_group_name': { ... data ... }
     'other_group_name': { ... data ... }
}
</code>```

Also each user enters email and password when entered to the app. On the sign up, he chooses the group name. For example in the sign up he will set username, password and some_group_name. But How do I connect between the currently login user and it's group in the database? The only data that Firebase authentication saves is email and password.

Do I need to create another collection users like so?

```<code>"users": {
    "some_user_name": "some_group_name"
}

</code>```

答:
You'll need to store the group membership/association of the user somewhere. How to do this, depends on the exact requirements of your app.

If a user can be a member of only one group, you can store their group as a field in a user profile doc. You'd typically have a top-level collection users for this, and a document for each user under that with the user's UID as the document ID (so that you can easily look up the user profile by their UID).

If a user can be a member of multiple groups, you can store that in an array field in the same user profile document. In that case, use arrayUnion and arrayRemove to manipulate the array, so that you can easily query for array membership when needed.

Body:
So I'm trying to understand how Firebase works. I'm using Firebase cloud for the Database. I have created a collection like this:

'groups': {
     'some_group_name': { ... data ... }
     'other_group_name': { ... data ... }
}

Also each user enters email and password when entered to the app. On the sign up, he chooses the group name. For example in the sign up he will set username, password and some_group_name. But How do I connect between the currently login user and it's group in the database? The only data that Firebase authentication saves is email and password.

Do I need to create another collection users like so?

"users": {
    "some_user_name": "some_group_name"
}


问:
Adobe illustrator Script paste
I found that command app.paste() but it doesnt return string its just pasting into document text. Basicaly i need command that return clipboard!

http://wwwimages.adobe.com/content/dam/Adobe/en/devnet/illustrator/sdk/CC2015_3/Illustrator%20JavaScript%20Scripting%20Reference.pdf

http://prntscr.com/cg5qtb

答:
app.paste() causes the new layer it creates to be the only selected layer, so you can access the text contents by returning its .contents property like this:

```<code>#target illustrator

function getClipboard() {
    var doc = app.activeDocument;
    var clipboard = '';

    app.paste();
    clipboard = doc.selection[0].contents;
    doc.selection[0].remove();

    return clipboard;
}
function main() {
    alert( getClipboard() );
}
main();```
```

Title: Adobe illustrator Script paste

Body:
app.paste() causes the new layer it creates to be the only selected layer, so you can access the text contents by returning its .contents property like this:

#target illustrator

function getClipboard() {
    var doc = app.activeDocument;
    var clipboard = '';

    app.paste();
    clipboard = doc.selection[0].contents;
    doc.selection[0].remove();

    return clipboard;
}
function main() {
    alert( getClipboard() );
}
main();```


答:
This fixes the coloring, plots the line of predicted values, and gets rid of the boxes in the legend:

```<code>df %>%
  ggplot(aes(x = Date, y = Count)) +
  geom_point(aes(color="Count")) +
  geom_line(aes(color="Count")) +
  geom_ribbon(data = forecast_df,
              aes(
                  y = forecast_point,
                  ymax = forecast_upper,
                  ymin = forecast_lower,
                  color="blue"),
              fill = "gray90",
              alpha = 0.5,
              , show.legend=FALSE)+
  geom_line(data=forecast_df, aes(x=Date, y = forecast_point)) +
  scale_colour_manual(labels = c("95% C.I.", "observed"),
                      values=c("black", "blue")) +
  theme_bw() +
  theme(legend.position = "bottom",
        legend.box = "vertical")+
  labs(colour = NULL)+
  scale_y_continuous("Y") +
  scale_x_date(date_breaks = "1 month",
               date_labels = "%b/%d")
</code>```

Title: ggplot2: legend mixes color and hide line for forecast graph

Body:
I'm using ggplot to plot forecast data. When I tried to show the legend, the color of the legends doesn't reflect the specified colors in the geom_line & geom_point. Also, the legend is shown in square box, which I'm trying to get rid off. I have used geom_ribbon to show the upper and lower values of the prediction results, However, the line of the predicted values is not shown and confidence interval was added to legend. I not sure what I'm missing. Any suggestions

here is my code :

library(ggplot2)
library(forecast)
df<-structure(list(Date = structure(c(18316, 18317, 18318, 18319,
                                      18320, 18321, 18322, 18323, 18324, 18325, 18326, 18327, 18328,
                                      18329, 18330, 18331, 18332, 18333, 18334, 18335, 18336, 18337,
                                      18338, 18339, 18340, 18341, 18342, 18343, 18344, 18345, 18346,
                                      18347, 18348, 18349, 18350, 18351, 18352, 18353, 18354, 18355,
                                      18356, 18357, 18358, 18359, 18360, 18361, 18362, 18363, 18364,
                                      18365, 18366, 18367, 18368, 18369, 18370, 18371, 18372, 18373,
                                      18374, 18375, 18376, 18377, 18378, 18379, 18380, 18381, 18382,
                                      18383, 18384, 18385, 18386, 18387, 18388, 18389, 18390, 18391,
                                      18392, 18393, 18394, 18395, 18396, 18397, 18398, 18399, 18400,
                                      18401, 18402, 18403, 18404, 18405, 18406, 18407, 18408, 18409,
                                      18410), class = "Date"), Count = c(5L, 11L, 26L, 43L, 45L, 45L,
                                                                         46L, 56L, 56L, 56L, 57L, 57L, 60L, 63L, 63L, 67L, 67L, 75L, 95L,
                                                                         97L, 103L, 111L, 118L, 127L, 130L, 137L, 149L, 158L, 159L, 152L,
                                                                         152L, 159L, 168L, 171L, 188L, 194L, 216L, 237L, 261L, 335L, 385L,
                                                                         456L, 561L, 637L, 743L, 798L, 869L, 1020L, 1091L, 1148L, 1176L,
                                                                         1196L, 1296L, 1395L, 1465L, 1603L, 1619L, 1657L, 1792L, 1887L,
                                                                         1986L, 2217L, 2249L, 2254L, 2241L, 2327L, 2459L, 2745L, 2883L,
                                                                         3169L, 3291L, 3732L, 4028L, 4142L, 4695L, 4952L, 5901L, 6314L,
                                                                         7101L, 7683L, 8436L, 9124L, 9852L, 10645L, 11234L, 11962L, 12559L,
                                                                         13275L, 13911L, 14569L, 15029L, 15181L, 15097L, 15146L, 15229L
                                      )), class = "data.frame", row.names = c(NA, -95L))

# frequency here in days
tm<-ts(df$Count,frequency = 365.25 )

fit.xts <- auto.arima(tm)
forecast_length <- 40
fore.xts <- forecast(fit.xts, h=forecast_length)

Date <- seq(max(df$Date) + 1, max(df$Date) + 40, "day")
forecast_point <- fore.xts$mean
forecast_lower <- fore.xts$lower[,2]
forecast_upper <- fore.xts$upper[,2]

forecast_df <- tibble(Date, forecast_point, forecast_lower, forecast_upper)

df %>%
  ggplot(aes(x = Date, y = Count)) +
  geom_point(aes(color="Count")) +
  geom_line(aes(color="Count")) +
  geom_ribbon(data = forecast_df,
              aes(x = Date,
                  y = forecast_point,
                  ymax = forecast_upper,
                  ymin = forecast_lower,
                  color="blue"),
              fill = "gray90",
              alpha = 0.5)+
  scale_colour_manual(labels = c("observed", "95% C.I."),
                      values=c("black", "blue")) +
  theme_bw() +
  theme(legend.position = "bottom",
        legend.box = "vertical")+
  labs(colour = NULL)+
  scale_y_continuous("Y") +
  scale_x_date(date_breaks = "1 month",
               date_labels = "%b/%d")

Body:
This fixes the coloring, plots the line of predicted values, and gets rid of the boxes in the legend:

df %>%
  ggplot(aes(x = Date, y = Count)) +
  geom_point(aes(color="Count")) +
  geom_line(aes(color="Count")) +
  geom_ribbon(data = forecast_df,
              aes(
                  y = forecast_point,
                  ymax = forecast_upper,
                  ymin = forecast_lower,
                  color="blue"),
              fill = "gray90",
              alpha = 0.5,
              , show.legend=FALSE)+
  geom_line(data=forecast_df, aes(x=Date, y = forecast_point)) +
  scale_colour_manual(labels = c("95% C.I.", "observed"),
                      values=c("black", "blue")) +
  theme_bw() +
  theme(legend.position = "bottom",
        legend.box = "vertical")+
  labs(colour = NULL)+
  scale_y_continuous("Y") +
  scale_x_date(date_breaks = "1 month",
               date_labels = "%b/%d")


问:
Custom Rails Validation throwing undefined method error
I need to validate that a field is a positive value, and wrote a little methid in lib/validations.rb which does exactly that and added it to my model. However, now one of my rspec tests is failing complaining...

NoMethodError: undefined method '<' for nil:NilClass"

...when the value is undefined. I've also added validates_presence_of :price to my model, above my custom validates_positive_or_zero method.

I would think that validates_presence_of would be called first, and when the field is nil it wouldn't run further validation. Do I have to change my validates_positive_or_zero method to check if the field exists to fix this? Can anyone give me some insight into what's going on?

答:
Rails already has this:

http://apidock.com/rails/ActiveModel/Validations/HelperMethods/validates_numericality_of

Use :greater_than => 0


问:
How do I measure elapsed time in Python?
I want to measure the time it took to execute a function. I couldn't get timeit to work:

```<code>import timeit
start = timeit.timeit()
print("hello")
end = timeit.timeit()
print(end - start)
</code>```

答:
The easiest way to calculate the duration of an operation:

```<code>import time

start_time = time.monotonic()

<operations, programs>

print('seconds: ', time.monotonic() - start_time)
</code>```

Official docs here.

Body:
I want to measure the time it took to execute a function. I couldn't get timeit to work:

import timeit
start = timeit.timeit()
print("hello")
end = timeit.timeit()
print(end - start)

Body:
The easiest way to calculate the duration of an operation:

import time

start_time = time.monotonic()

<operations, programs>

print('seconds: ', time.monotonic() - start_time)

Official docs here.


问:
Find the closest point on a cylinder surface to a given line in c++
I need a function that will find the closest point on a cylinder surface to a given line. Let's say the cylinder is centered along the z-axis({0, 0, 0}) and defined by its Radius R and half-length Z and the (infinite) line is defined by two 3D points A(x1,x2) and B(y1,y2). What is the best way to compute the point on the cylinder surface which is closest to this line? </p>

答:
Consider skew lines in 3D - z-axis and your line.

Build the shortest line between them (it is perpensicular to both line).

Math of this calculation is described in "the shortest line" section here, example of implementation is here.

If point S on z-axis (where the shortest line meets z-axis) is outside of cylinder, then the closest point lies on the circumference of cylinder top or bottom (use direction vector described below with zero z-component)

Otherwise calculate unit vector for the shortest line direction, multiply it by cylinder radius, add to point S

Also check case of distance < R - when line intersects cylinder.


问:
How to scrape a public tableau dashboard?
Every day I need to downlaod the data available on a public Tableau dashboard. After defining the parameters of interest (time series frequency, time series interval, etc) the dashboard allows you to download the series.

My life would be reasonably easier if I could automate the download of these series to a database using Python or R. I've already tried to analyze the requests made on the page but I couldn't get much further. Is there any way to automate this process?

The dashboard: https://tableau.ons.org.br/t/ONS_Publico/views/DemandaMxima/HistricoDemandaMxima?:embed=y&:showAppBanner=false&:showShareOptions=true&:display_count=no&:showVizHome=no

答:
Edit

I've made a tableau scraper library to extract the data from Tableau worksheets

You can get the data from worksheets in a pandas dataframe directly. Also, the parametered values are supported.

The following example get the data from worksheet Simples Demanda Máxima Ano, then switch to daily mode, shows the worksheet Simples Demanda Máxima Semana Dia data and then set start date to 01/01/2017 :

from tableauscraper import TableauScraper as TS

url = "https://tableau.ons.org.br/t/ONS_Publico/views/DemandaMxima/HistricoDemandaMxima"

ts = TS()
ts.loads(url)
wb = ts.getWorkbook()

# show dataframe with yearly data
ws = wb.getWorksheet("Simples Demanda Máxima Ano")
print(ws.data)

# switch to daily
wb = wb.setParameter("Escala de Tempo DM Simp 4", "Dia")

# show dataframe with daily data
ws = wb.getWorksheet("Simples Demanda Máxima Semana Dia")
print(ws.data)

# switch to daily
wb = wb.setParameter(
    "Início Primeiro Período DM Simp 4", "01/01/2017")

# show dataframe with daily data from 01/01/2017
ws = wb.getWorksheet("Simples Demanda Máxima Semana Dia")
print(ws.data)

```
<p>Try this on repl.it</p>
<hr />
<h3>Original post</h3>
<p>This answer is similar to this one but the initial URL page and tableau base URL differ. The process/algo remains the same essentially but I will details the steps :</p>
<p>The graphic is generated in JS from the result of an API :</p>
```POST https://tableau.ons.org.br/ROOT_PATH/bootstrapSession/sessions/SESSION_ID
```
<p>The <code>SESSION_ID</code> parameter is located (among other things) in <code>tsConfigContainer</code> textarea in the URL used to build the iframe.</p>
<p>Starting from https://tableau.ons.org.br/t/ONS_Publico/views/DemandaMxima/HistricoDemandaMxima?:embed=y&:showAppBanner=false&:showShareOptions=true&:display_count=no&:showVizHome=no :</p>
<ul>
<li>there is a textarea with id <code>tsConfigContainer</code> with a bunch of json values</li>
<li>extract the <code>session_id</code> and root path (<code>vizql_root</code>)</li>
<li>make a POST on <code>https://tableau.ons.org.br/ROOT_PATH/bootstrapSession/sessions/SESSION_ID</code> with the <code>sheetId</code> as form data</li>
<li>extract the json from the result (result is not json)</li>
</ul>
<p>Code :</p>
```import requests
from bs4 import BeautifulSoup
import json
import re

url = "https://tableau.ons.org.br/t/ONS_Publico/views/DemandaMxima/HistricoDemandaMxima"

r = requests.get(
    url,
    params= {
        ":embed":"y",
        ":showAppBanner":"false",
        ":showShareOptions":"true",
        ":display_count":"no",
        "showVizHome": "no"
    }
)
soup = BeautifulSoup(r.text, "html.parser")

tableauData = json.loads(soup.find("textarea",{"id": "tsConfigContainer"}).text)

dataUrl = f'https://tableau.ons.org.br{tableauData["vizql_root"]}/bootstrapSession/sessions/{tableauData["sessionid"]}'

r = requests.post(dataUrl, data= {
    "sheet_id": tableauData["sheetId"],
})

dataReg = re.search('\d+;({.*})\d+;({.*})', r.text, re.MULTILINE)
info = json.loads(dataReg.group(1))
data = json.loads(dataReg.group(2))

print(data["secondaryInfo"]["presModelMap"]["dataDictionary"]["presModelHolder"]["genDataDictionaryPresModel"]["dataSegments"]["0"]["dataColumns"])
```

Body:
Edit

I've made a tableau scraper library to extract the data from Tableau worksheets

You can get the data from worksheets in a pandas dataframe directly. Also, the parametered values are supported.

The following example get the data from worksheet Simples Demanda Máxima Ano, then switch to daily mode, shows the worksheet Simples Demanda Máxima Semana Dia data and then set start date to 01/01/2017 :

from tableauscraper import TableauScraper as TS

url = "https://tableau.ons.org.br/t/ONS_Publico/views/DemandaMxima/HistricoDemandaMxima"

ts = TS()
ts.loads(url)
wb = ts.getWorkbook()

# show dataframe with yearly data
ws = wb.getWorksheet("Simples Demanda Máxima Ano")
print(ws.data)

# switch to daily
wb = wb.setParameter("Escala de Tempo DM Simp 4", "Dia")

# show dataframe with daily data
ws = wb.getWorksheet("Simples Demanda Máxima Semana Dia")
print(ws.data)

# switch to daily
wb = wb.setParameter(
    "Início Primeiro Período DM Simp 4", "01/01/2017")

# show dataframe with daily data from 01/01/2017
ws = wb.getWorksheet("Simples Demanda Máxima Semana Dia")
print(ws.data)

Try this on repl.it

Original post

This answer is similar to this one but the initial URL page and tableau base URL differ. The process/algo remains the same essentially but I will details the steps :

The graphic is generated in JS from the result of an API :

POST https://tableau.ons.org.br/ROOT_PATH/bootstrapSession/sessions/SESSION_ID

The SESSION_ID parameter is located (among other things) in tsConfigContainer textarea in the URL used to build the iframe.

Starting from https://tableau.ons.org.br/t/ONS_Publico/views/DemandaMxima/HistricoDemandaMxima?:embed=y&:showAppBanner=false&:showShareOptions=true&:display_count=no&:showVizHome=no :

there is a textarea with id tsConfigContainer with a bunch of json values

extract the session_id and root path (vizql_root)

make a POST on https://tableau.ons.org.br/ROOT_PATH/bootstrapSession/sessions/SESSION_ID with the sheetId as form data

extract the json from the result (result is not json)

Code :

import requests
from bs4 import BeautifulSoup
import json
import re

url = "https://tableau.ons.org.br/t/ONS_Publico/views/DemandaMxima/HistricoDemandaMxima"

r = requests.get(
    url,
    params= {
        ":embed":"y",
        ":showAppBanner":"false",
        ":showShareOptions":"true",
        ":display_count":"no",
        "showVizHome": "no"
    }
)
soup = BeautifulSoup(r.text, "html.parser")

tableauData = json.loads(soup.find("textarea",{"id": "tsConfigContainer"}).text)

dataUrl = f'https://tableau.ons.org.br{tableauData["vizql_root"]}/bootstrapSession/sessions/{tableauData["sessionid"]}'

r = requests.post(dataUrl, data= {
    "sheet_id": tableauData["sheetId"],
})

dataReg = re.search('\d+;({.*})\d+;({.*})', r.text, re.MULTILINE)
info = json.loads(dataReg.group(1))
data = json.loads(dataReg.group(2))

print(data["secondaryInfo"]["presModelMap"]["dataDictionary"]["presModelHolder"]["genDataDictionaryPresModel"]["dataSegments"]["0"]["dataColumns"])


问:
Two JSFiddles with the exact same code but one works and the other doesn't
The following SJFiddle works fine.

http://jsfiddle.net/JMPerez/62wafrm7/

I created a second SJFiddle to test it and copied everything (HTML/CSS/JS) exactly the same from the first one. I also included the same resources but it doesn't work.

https://jsfiddle.net/kennethcode/dz1tubf6/

HTML is the same for both

```<code><div class="container">
    <h1>Displaying User Data</h1>
    <p>Log in with your Spotify account and this demo will display information about you fetched using the Spotify Web API</p>
    <button class="btn btn-primary" id="btn-login">Login</button>
    <div id="result"></div>
</div>
<script id="result-template" type="text/x-handlebars-template">
    <dl>
      <img src="{{images.0.url}}">
      <dt>User Name</dt>
      <dd>{{id}}</dd>
      <dt>Display Name</dt>
      <dd>{{display_name}}</dd>
      <dt>Country</dt>
      <dd>{{country}}</dd>
      <dt>Followers</dt>
      <dd>{{followers.total}}</dd>
      <dt>Profile</dt>
      <dd><a href="{{external_urls.spotify}}" target="_blank">{{external_urls.spotify}}</a></dd>
      <dt>Email</dt>
      <dd>{{email}}</dd>
      <dt>Product</dt>
      <dd>{{product}}</dd>
    </dl>
</script>
</code>```

JavaScript is the same for both

```<code>(function() {

    function login(callback) {
        var CLIENT_ID = '6b284830006843e7ae7b170725715aed';
        var REDIRECT_URI = 'http://jmperezperez.com/spotify-oauth-jsfiddle-proxy/';
        function getLoginURL(scopes) {
            return 'https://accounts.spotify.com/authorize?client_id=' + CLIENT_ID +
              '&redirect_uri=' + encodeURIComponent(REDIRECT_URI) +
              '&scope=' + encodeURIComponent(scopes.join(' ')) +
              '&response_type=token';
        }

        var url = getLoginURL([
            'user-read-email'
        ]);

        var width = 450,
            height = 730,
            left = (screen.width / 2) - (width / 2),
            top = (screen.height / 2) - (height / 2);

        window.addEventListener("message", function(event) {
            var hash = JSON.parse(event.data);
            if (hash.type == 'access_token') {
                callback(hash.access_token);
            }
        }, false);

        var w = window.open(url,
                            'Spotify',
                            'menubar=no,location=no,resizable=no,scrollbars=no,status=no, width=' + width + ', height=' + height + ', top=' + top + ', left=' + left
                           );

    }

    function getUserData(accessToken) {
        return $.ajax({
            url: 'https://api.spotify.com/v1/me',
            headers: {
               'Authorization': 'Bearer ' + accessToken
            }
        });
    }

    var templateSource = document.getElementById('result-template').innerHTML,
        template = Handlebars.compile(templateSource),
        resultsPlaceholder = document.getElementById('result'),
        loginButton = document.getElementById('btn-login');

    loginButton.addEventListener('click', function() {
        login(function(accessToken) {
            getUserData(accessToken)
                .then(function(response) {
                    loginButton.style.display = 'none';
                    resultsPlaceholder.innerHTML = template(response);
                });
            });
    });

})();
</code>```

CSS is the same for both

```<code>.container {
    margin: 1em;
}

img {
    margin-bottom: 1em;
}
</code>```

Any clues why this might be happening? Thanks

答:
Check the “Resources” section in the sidebar. The first one has these 3 additional resources:

cached.css

handlebars.min.js

jquery-1.10.1.min.js

Body:
The following SJFiddle works fine.

http://jsfiddle.net/JMPerez/62wafrm7/

I created a second SJFiddle to test it and copied everything (HTML/CSS/JS) exactly the same from the first one. I also included the same resources but it doesn't work.

https://jsfiddle.net/kennethcode/dz1tubf6/

HTML is the same for both

Displaying User Data

Log in with your Spotify account and this demo will display information about you fetched using the Spotify Web API

    <button class="btn btn-primary" id="btn-login">Login</button>

JavaScript is the same for both

(function() {

    function login(callback) {
        var CLIENT_ID = '6b284830006843e7ae7b170725715aed';
        var REDIRECT_URI = 'http://jmperezperez.com/spotify-oauth-jsfiddle-proxy/';
        function getLoginURL(scopes) {
            return 'https://accounts.spotify.com/authorize?client_id=' + CLIENT_ID +
              '&redirect_uri=' + encodeURIComponent(REDIRECT_URI) +
              '&scope=' + encodeURIComponent(scopes.join(' ')) +
              '&response_type=token';
        }

        var url = getLoginURL([
            'user-read-email'
        ]);

        var width = 450,
            height = 730,
            left = (screen.width / 2) - (width / 2),
            top = (screen.height / 2) - (height / 2);

        window.addEventListener("message", function(event) {
            var hash = JSON.parse(event.data);
            if (hash.type == 'access_token') {
                callback(hash.access_token);
            }
        }, false);

        var w = window.open(url,
                            'Spotify',
                            'menubar=no,location=no,resizable=no,scrollbars=no,status=no, width=' + width + ', height=' + height + ', top=' + top + ', left=' + left
                           );

    }

    function getUserData(accessToken) {
        return $.ajax({
            url: 'https://api.spotify.com/v1/me',
            headers: {
               'Authorization': 'Bearer ' + accessToken
            }
        });
    }

    var templateSource = document.getElementById('result-template').innerHTML,
        template = Handlebars.compile(templateSource),
        resultsPlaceholder = document.getElementById('result'),
        loginButton = document.getElementById('btn-login');

    loginButton.addEventListener('click', function() {
        login(function(accessToken) {
            getUserData(accessToken)
                .then(function(response) {
                    loginButton.style.display = 'none';
                    resultsPlaceholder.innerHTML = template(response);
                });
            });
    });

})();

CSS is the same for both

.container {
    margin: 1em;
}

img {
    margin-bottom: 1em;
}

Any clues why this might be happening? Thanks


问:
When planning a FFT, can I use the same plan for an inverse FFT?
I am working with a 3D array of real floats.

In one part of my code, I am supposed to take a 3DFFT of these values, and then dot the resulting complex matrix with another matrix of floats. (dot = pointwise multiplication)

Then I take the inverse FFT and update the initial array.

What is important when you do the first cufftPlan3d()?
i.e.What is the Plan really looking for?

Does the plan just need to see the dimensions and the type of the array to work quickly, or is it also looking at the magnitudes of the real and complex parts?

I am trying to use the plan as little as possible so that I can compute the transforms faster, but I also want the FFTs (and the iFFTs) to be as fast as possible as this is the bottleneck of the code.

My first thought is that I would make a plan before the initial FFT and then make another plan after the resulting dot product/FFT for the inverse FFT and then use these 2 plans everywhere later in the loop.

Thanks for any suggestions.

答:
You should definitely be able to create just one plan and reuse it everywhere in the loop, as long as the type and size of the transform does not change.  It sounds like that is the case for you.  In fact, you can use the same plan for both forward (FFT) and reverse (iFFT) transforms as long as the type and size are the same, since CUFFT_FORWARD / CUFFT_REVERSE are parameters for cufftExec*(), not for cufftPlan*().

If you have multiple sizes and types to support, create a separate plan for each type/size combination at startup (if you know them ahead of time).


问:
Flutter - How to enable control-flow-collection?
I'm trying use control-flow-collections in Flutter(Google's UI toolkit) to enable the use of inline for loop, i.e:

```<code>for (int i = 0; i < globals.currentScaleList.scales.length; i++)
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Text(
                    globals.currentScaleList.scales[i].scaleType.toString(),
                    style: TextStyle(fontSize: 20.0),
                  ),
                ],
              ),
          ], itemExtent: 23.0, onSelectedItemChanged: (index) {}),
</code>```

I have seen the other questions on the topics in SO and followed all of the instructions that seem to work for others.

I am running Flutter 1.15.4-pre.248 on the Master channel and Dart 2.8.0

```<code>Flutter 1.15.4-pre.248 • channel master • https://github.com/flutter/flutter.git
Framework • revision 686d163420 (2 hours ago) • 2020-03-02 16:25:22 -0500
Engine • revision 5e474ee860
Tools • Dart 2.8.0 (build 2.8.0-dev.10.0 fbe9f6115d)
</code>```

I have created a analysis_options.yaml file in my root app folder and added the following:

```<code>analyzer:
  enable-experiment:
    - control-flow-collections
</code>```

I have also updated the min version of Dart in my pubspec.yaml, i.e.:

```<code>environment:
  sdk: ">=2.5.0 <3.0.0"
</code>```

However, I still get the error against my 'for' loop stating:

"This requires the 'control-flow-collections' experiment to be enabled.
Try enabling this experiment by adding it to the command line when compiling and running."

When I do enable the 3 lines in my analysis_options.yaml file, I get the warning:

"The option 'control-flow-collection' isn't supported by 'enable-experiment'."

What am I missing? Thanks

答:
For those who are facing this issue and have tried creating the analysis_options.yaml, I did what Paul Toal said on the last comment.

Remove analysis_options.yaml (if created)

Run flutter clean command

Restart VSCode

This one worked for me, using the following.

```<code>environment:
  sdk: ">=2.5.2 <3.0.0"
</code>```

Body:
I'm trying use control-flow-collections in Flutter(Google's UI toolkit) to enable the use of inline for loop, i.e:

for (int i = 0; i < globals.currentScaleList.scales.length; i++)
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Text(
                    globals.currentScaleList.scales[i].scaleType.toString(),
                    style: TextStyle(fontSize: 20.0),
                  ),
                ],
              ),
          ], itemExtent: 23.0, onSelectedItemChanged: (index) {}),

I have seen the other questions on the topics in SO and followed all of the instructions that seem to work for others.

I am running Flutter 1.15.4-pre.248 on the Master channel and Dart 2.8.0

Flutter 1.15.4-pre.248 • channel master • https://github.com/flutter/flutter.git
Framework • revision 686d163420 (2 hours ago) • 2020-03-02 16:25:22 -0500
Engine • revision 5e474ee860
Tools • Dart 2.8.0 (build 2.8.0-dev.10.0 fbe9f6115d)

I have created a analysis_options.yaml file in my root app folder and added the following:

analyzer:
  enable-experiment:
    - control-flow-collections

I have also updated the min version of Dart in my pubspec.yaml, i.e.:

environment:
  sdk: ">=2.5.0 <3.0.0"

However, I still get the error against my 'for' loop stating:

"This requires the 'control-flow-collections' experiment to be enabled.
Try enabling this experiment by adding it to the command line when compiling and running."

When I do enable the 3 lines in my analysis_options.yaml file, I get the warning:

"The option 'control-flow-collection' isn't supported by 'enable-experiment'."

What am I missing? Thanks

Body:
For those who are facing this issue and have tried creating the analysis_options.yaml, I did what Paul Toal said on the last comment.

Remove analysis_options.yaml (if created)

Run flutter clean command

Restart VSCode

This one worked for me, using the following.

environment:
  sdk: ">=2.5.2 <3.0.0"


问:
MySQL: To exclude some results based on specified conditions
I am stuck at some problem. The problem has two tables, namely hackers and challenges.
Here is the schema:

```<code>Hackers(hacker_id: int, name string)
Challenges(challenge_id: int, hacker_id int)
</code>```

I am trying to write a query to print the hacker_id, name, and the total number of challenges created by each student. Sort your results by the total number of challenges in descending order. If more than one student created the same number of challenges, then sort the result by hacker_id. If more than one student created the same number of challenges and the count is less than the maximum number of challenges created, then exclude those students from the result.

Here is my query:

```<code>select hackers.hacker_id ,
       hackers.name ,
       count(challenges.challenge_id) as challenges_created
       from
       hackers left join  challenges
       on
       hackers.hacker_id = challenges.hacker_id
       having
       count(challenges_created) >= max(challenges_created)
       order by challenges_created desc, hackers.hacker_id asc
</code>```

I am getting wrong output!
Please tell me where I am getting wrong!

Sample Input :

Hackers Table:image
Challengers Table :image

```<code>Sample Output:
21283  Angela  6
88255  Patrick  5
96196  Lisa  1
</code>```

答:
try this it's very simple....</p>

```<code>select
    h.hacker_id,
    h.name
from hackers h, difficulty d, challenges c, submissions s
where
    h.hacker_id=s.hacker_id
and s.challenge_id=c.challenge_id
and d.difficulty_level=c.difficulty_level
and d.score=s.score
group by h.hacker_id, h.name
having count(*)>1
ORDER BY COUNT(*) DESC, h.hacker_id;
</code>```

Body:
I am stuck at some problem. The problem has two tables, namely hackers and challenges.
Here is the schema:

Hackers(hacker_id: int, name string)
Challenges(challenge_id: int, hacker_id int)

I am trying to write a query to print the hacker_id, name, and the total number of challenges created by each student. Sort your results by the total number of challenges in descending order. If more than one student created the same number of challenges, then sort the result by hacker_id. If more than one student created the same number of challenges and the count is less than the maximum number of challenges created, then exclude those students from the result.

Here is my query:

select hackers.hacker_id ,
       hackers.name ,
       count(challenges.challenge_id) as challenges_created
       from
       hackers left join  challenges
       on
       hackers.hacker_id = challenges.hacker_id
       having
       count(challenges_created) >= max(challenges_created)
       order by challenges_created desc, hackers.hacker_id asc

I am getting wrong output!
Please tell me where I am getting wrong!

Sample Input :

Hackers Table:image
Challengers Table :image

Sample Output:
21283  Angela  6
88255  Patrick  5
96196  Lisa  1

Body:
try this it's very simple....

select
    h.hacker_id,
    h.name
from hackers h, difficulty d, challenges c, submissions s
where
    h.hacker_id=s.hacker_id
and s.challenge_id=c.challenge_id
and d.difficulty_level=c.difficulty_level
and d.score=s.score
group by h.hacker_id, h.name
having count(*)>1
ORDER BY COUNT(*) DESC, h.hacker_id;


问:
Use Date as local, not UTC when using it from bootstrap date picker
I need to get date from an angular reactive form. Then I need to use the date, stringfy it and store it in a session storage. I would like the date to be in a format that not contains time stamp, but only the date (hence - mm/dd/yyyy or dd/mm/yyyy, or any other format). I don't want it to be used as a UTC time - just use it as local. I keep on getting the date in a UTC - so if I'm UTC+2, I get the date converted to be the day before hour 22:00.
Using it as string is one way doing it, but I would like to have it as date
What is the best way to configure the datepicker\do it so that the JSON.stringify won't use a UTC convention and treat it as local date - setting it as string and not as a date object ?

See my code:
HTML:

```<code>    <mat-form-field>
      <mat-label>Date Of Birth</mat-label>
      <input matInput [matDatepicker]="picker" formControlName="DateOfBirth">
      <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
      <mat-datepicker #picker></mat-datepicker>
    </mat-form-field>
    <button mat-raised-button type="submit" (click)="saveUserDetails()">
</code>```

Component:

```<code>ngOnInit() {
    if (this.userService.userDataInSession && this.userService.userDataInSession.FirstName)
    {
        let sessionUserData = this.userService.userDataInSession;
        this.userDetailsForm = this.fb.group(
        {
            DateOfBirth:[sessionUserData.DateOfBirth]
        }
    }
    else
    {
       this.userDetailsForm = this.fb.group(
       {
           DateOfBirth:['']
       }
    }
}

saveUserDetails()
{
   this.userDetailsData.initByFormControls(this.userDetailsForm.controls);
   this.userService.userDataInSession = this.userDetailsData;
}
</code>```

In userDetailsData (model):

```<code>public initByFormControls(formControls : any)
{
    Object.keys(this).forEach(key =>
    {
        if (formControls[key])
        {
            this[key] = formControls[key].value;
        }
    });
}
</code>```

UserServise:

```<code>export class UserService
{
    get userDataInSession() : UserData
    {
     if (!sessionStorage.getItem("userData") || sessionStorage.getItem("userData") == "undefined")
     {
       return new UserData();
     }
     else
     {
       return JSON.parse(sessionStorage.getItem("userData"));
     }
   }
   set userDataInSession(value)
   {

    sessionStorage.setItem("userData", JSON.stringify(value));
   }
   setUserDataProperty(propertyName : string, value : any)
   {
    if (this.userDataInSession.hasOwnProperty(propertyName))
    {
      this.userDataInSession[propertyName] = value;
      this.userDataInSession = this.userDataInSession;
    }
  }
}
</code>```

答:
The JavaScript Date object stores dates in UTC.

If you want the date in the local time zone, you output the results of the Date object in that timezone. For example, to get the current date in the local timezone:

let now = new Date();
let nowYear = now.getFullYear();
let nowMonth = now.getMonth() + 1;
let monthStr = ('0'+nowMonth).slice(-2);
let nowDate = now.getDate();
let dateStr = ('0'+nowDate).slice(-2);
let date = monthStr + '/' + dateStr + '/' + nowYear
console.log('date in local timezone:', date)```

Body:
I need to get date from an angular reactive form. Then I need to use the date, stringfy it and store it in a session storage. I would like the date to be in a format that not contains time stamp, but only the date (hence - mm/dd/yyyy or dd/mm/yyyy, or any other format). I don't want it to be used as a UTC time - just use it as local. I keep on getting the date in a UTC - so if I'm UTC+2, I get the date converted to be the day before hour 22:00.
Using it as string is one way doing it, but I would like to have it as date
What is the best way to configure the datepicker\do it so that the JSON.stringify won't use a UTC convention and treat it as local date - setting it as string and not as a date object ?

See my code:
HTML:

    <mat-form-field>
      <mat-label>Date Of Birth</mat-label>
      <input matInput [matDatepicker]="picker" formControlName="DateOfBirth">
      <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
      <mat-datepicker #picker></mat-datepicker>
    </mat-form-field>
    <button mat-raised-button type="submit" (click)="saveUserDetails()">

Component:

ngOnInit() {
    if (this.userService.userDataInSession && this.userService.userDataInSession.FirstName)
    {
        let sessionUserData = this.userService.userDataInSession;
        this.userDetailsForm = this.fb.group(
        {
            DateOfBirth:[sessionUserData.DateOfBirth]
        }
    }
    else
    {
       this.userDetailsForm = this.fb.group(
       {
           DateOfBirth:['']
       }
    }
}

saveUserDetails()
{
   this.userDetailsData.initByFormControls(this.userDetailsForm.controls);
   this.userService.userDataInSession = this.userDetailsData;
}

In userDetailsData (model):

public initByFormControls(formControls : any)
{
    Object.keys(this).forEach(key =>
    {
        if (formControls[key])
        {
            this[key] = formControls[key].value;
        }
    });
}

UserServise:

export class UserService
{
    get userDataInSession() : UserData
    {
     if (!sessionStorage.getItem("userData") || sessionStorage.getItem("userData") == "undefined")
     {
       return new UserData();
     }
     else
     {
       return JSON.parse(sessionStorage.getItem("userData"));
     }
   }
   set userDataInSession(value)
   {

    sessionStorage.setItem("userData", JSON.stringify(value));
   }
   setUserDataProperty(propertyName : string, value : any)
   {
    if (this.userDataInSession.hasOwnProperty(propertyName))
    {
      this.userDataInSession[propertyName] = value;
      this.userDataInSession = this.userDataInSession;
    }
  }
}


问:
JQuery loop though multidimensional json array using for loop
I am trying to loop through JSON data

```<code>{"reply":[{"ticketnumber":"61947"}],"all":[{"ticketnumber":"61947"}]);
</code>```

using

```<code>success: function(data) {
    for(var i in data) {
        console.log(data[i]);
    }
}
</code>```

but i cannot get the key values, so i want to get "reply" and "all" then loop through those inside the first loop

答:
You can use Object.keys and then loop the data inside "reply" and "all" using for..of like:

const data = {
  "reply": [{
    "ticketnumber": "61947"
  }],
  "all": [{
    "ticketnumber": "61947"
  }]
};

for (var key of Object.keys(data)) {
  console.log(key);
  for (var i of data[key]) {
    console.log(i);
  }
}```

Body:
I am trying to loop through JSON data

{"reply":[{"ticketnumber":"61947"}],"all":[{"ticketnumber":"61947"}]);

using

success: function(data) {
    for(var i in data) {
        console.log(data[i]);
    }
}

but i cannot get the key values, so i want to get "reply" and "all" then loop through those inside the first loop


问:
How can I merge keys with the same value into a single object?
I use the Parsehub API to scrape the data below in a json format and when I want to print information on a certain country I'm able to get only the first set of data: 'name', 'pop','area','growth','worldPer', and 'rank' but I'm unable to get 'image'.

When I print the entire json file, the data is all there, but when I try to print a countries data with the image value, I get a key error.

Is there a way I can merge the two objects by matching country name?

main.py

```<code>class Data:
    def __init__(self, api_key, project_token):
        self.api_key = api_key
        self.project_token = project_token
        self.params = {"api_key":api_key}
        self.data = self.get_data()

    def get_data(self):
        r = requests.get(f'https://www.parsehub.com/api/v2/projects/xxxx/last_ready_run/data', params={"api_key": DATA_API_KEY})
        data = json.loads(r.text)
        print(r.text)
        return data

    def data_by_name(self,country):
        data = self.data['country']
        for content in data:
            if content['name'].lower() == country.lower():
                print(content)
                name = content['name']
                pop = content['pop']
                popRank = content['rank']
                growth = content['growth']
                per = content['worldPer']
                area = content['area']
                image = content['image'] #<----- KeyError: 'image'
        return(name,pop,popRank,growth,per,area)

data = Data(DATA_API_KEY,DATA_PROJECT_TOKEN)
data.data_by_name('china')

</code>```

country.json

```<code>{
 "country": [
  {
   "name": "China",
   "pop": "1,438,862,614",
   "area": "9,706,961 km²",
   "growth": "0.39%",
   "worldPer": "18.47%",
   "rank": "1"
  },
  {
   "name": "China",
   "image": "https://s3.amazonaws.com/images.wpr.com/flag-pages/png250/cn.png"
  }
 ]
}
</code>```

答:
There are (at least) two ways to go about this: you could merge all the different entries with the same name, e.g. china, in the data. Or you could search through all the countries each time, and grab all the necessary data from each one that matches your country. Here's an example of the 2nd one, where I modify your data_by_name method. The advantage of this is it works even if you don't know how many times the country might appear:

```<code>def data_by_name(self,country):
    data = self.data['country']
    my_dict = {}
    for content in data:
        if content['name'].lower() == country.lower():
            print(content)
            my_dict.update(content) # This updates your dict with the key/value pairs
    return my_dict     # my_dict will have all the different values, including image
</code>```

If you want only specific fields, you could return those:

```<code>    return (
        my_dict['name'],
        my_dict['pop'],
        my_dict['rank'],
        my_dict['growth'],
        my_dict['worldPer'],
        my_dict['area'],
        my_dict['image']
    )
</code>```

Hope that helps, happy coding!

Body:
I use the Parsehub API to scrape the data below in a json format and when I want to print information on a certain country I'm able to get only the first set of data: 'name', 'pop','area','growth','worldPer', and 'rank' but I'm unable to get 'image'.

When I print the entire json file, the data is all there, but when I try to print a countries data with the image value, I get a key error.

Is there a way I can merge the two objects by matching country name?

main.py

class Data:
    def __init__(self, api_key, project_token):
        self.api_key = api_key
        self.project_token = project_token
        self.params = {"api_key":api_key}
        self.data = self.get_data()

    def get_data(self):
        r = requests.get(f'https://www.parsehub.com/api/v2/projects/xxxx/last_ready_run/data', params={"api_key": DATA_API_KEY})
        data = json.loads(r.text)
        print(r.text)
        return data

    def data_by_name(self,country):
        data = self.data['country']
        for content in data:
            if content['name'].lower() == country.lower():
                print(content)
                name = content['name']
                pop = content['pop']
                popRank = content['rank']
                growth = content['growth']
                per = content['worldPer']
                area = content['area']
                image = content['image'] #<----- KeyError: 'image'
        return(name,pop,popRank,growth,per,area)

data = Data(DATA_API_KEY,DATA_PROJECT_TOKEN)
data.data_by_name('china')

country.json

{
 "country": [
  {
   "name": "China",
   "pop": "1,438,862,614",
   "area": "9,706,961 km²",
   "growth": "0.39%",
   "worldPer": "18.47%",
   "rank": "1"
  },
  {
   "name": "China",
   "image": "https://s3.amazonaws.com/images.wpr.com/flag-pages/png250/cn.png"
  }
 ]
}

Body:
There are (at least) two ways to go about this: you could merge all the different entries with the same name, e.g. china, in the data. Or you could search through all the countries each time, and grab all the necessary data from each one that matches your country. Here's an example of the 2nd one, where I modify your data_by_name method. The advantage of this is it works even if you don't know how many times the country might appear:

def data_by_name(self,country):
    data = self.data['country']
    my_dict = {}
    for content in data:
        if content['name'].lower() == country.lower():
            print(content)
            my_dict.update(content) # This updates your dict with the key/value pairs
    return my_dict     # my_dict will have all the different values, including image

If you want only specific fields, you could return those:

    return (
        my_dict['name'],
        my_dict['pop'],
        my_dict['rank'],
        my_dict['growth'],
        my_dict['worldPer'],
        my_dict['area'],
        my_dict['image']
    )

Hope that helps, happy coding!


问:
SSL certificate not working while making curl request - Sectigo AddTrust External CA Root expired
While I try to open some of domains like https://tracking.buyhatke.com , https://s1.ripple.com , they work perfectly fine, but when I try to make a curl request to these pages from terminal, it says the certificates have expired. In browser , the certificates show that there is long time to expiry.

```<code>curl "https://tracking.buyhatke.com"
curl "https://s1.ripple.com"
</code>```

Can anyone guide me what is wrong here ? And it started happening today, all of a sudden

答:
So, this happened because of the issuing Root CA certificates. This can be fixed on Ubuntu 16 in this way :-

```<code> 1. Edit /etc/ca-certificates.conf
 2. Remove mozilla/AddTrust_External_Root.crt
 3. sudo apt update && sudo apt install ca-certificates && sudo update-ca-certificates -f -v
</code>```

That fixed it for me

Edit

Adding some useful stuff which can help us fix it client side and server side based on your needs

https://www.agwa.name/blog/post/fixing_the_addtrust_root_expiration

Body:
While I try to open some of domains like https://tracking.buyhatke.com , https://s1.ripple.com , they work perfectly fine, but when I try to make a curl request to these pages from terminal, it says the certificates have expired. In browser , the certificates show that there is long time to expiry.

curl "https://tracking.buyhatke.com"
curl "https://s1.ripple.com"

Can anyone guide me what is wrong here ? And it started happening today, all of a sudden

Body:
So, this happened because of the issuing Root CA certificates. This can be fixed on Ubuntu 16 in this way :-

 1. Edit /etc/ca-certificates.conf
 2. Remove mozilla/AddTrust_External_Root.crt
 3. sudo apt update && sudo apt install ca-certificates && sudo update-ca-certificates -f -v

That fixed it for me

Edit

Adding some useful stuff which can help us fix it client side and server side based on your needs

https://www.agwa.name/blog/post/fixing_the_addtrust_root_expiration


问:
How can I replace a hash key with another key?
I have a condition that gets a hash.

```<code>  hash = {"_id"=>"4de7140772f8be03da000018", .....}
</code>```

Yet, I want to rename the key of that hash as follows.

```<code>  hash = {"id"=>"4de7140772f8be03da000018", ......}
</code>```

P.S. I don't know what keys are in the hash; they are random. Some keys are prefixed with an underscore that I would like to remove.

答:
you can do </p>

```<code>hash.inject({}){|option, (k,v) | option["id"] = v if k == "_id"; option}
</code>```

<p>This should work for your case! </p>

Body:
I have a condition that gets a hash.

  hash = {"_id"=>"4de7140772f8be03da000018", .....}

Yet, I want to rename the key of that hash as follows.

  hash = {"id"=>"4de7140772f8be03da000018", ......}

P.S. I don't know what keys are in the hash; they are random. Some keys are prefixed with an underscore that I would like to remove.

Body:
you can do

hash.inject({}){|option, (k,v) | option["id"] = v if k == "_id"; option}

This should work for your case!


问:
Do docker volumes have to be hosted on the host machine?
I've used the Docker Desktop to get a Laravel site running and it's been successful. What I'm not sure of is how things should work in a production environment.

I've chosen to use two existing images: redis:4.0-alpine and mariadb:10.4.11. The other two images I made: recognizerhd/nginx-remote-log:latest and recognizerhd/php-fpm:latest. The containers all connect to the same network. There are two volumes, one for the database, and another for the Laravel files that are mounted to the nginx and PHP containers.

I am currently signed up with OVH, and I've looked a little into DigitalOcean. Host, I guess, is mostly irrelevant unless they don't offer even the basic needs to get a docker setup running.

I've created an instance and added a volume. I've had to mount that volume on the instance in order to access it. Am I understanding correctly that this is only the server level and a volume here has nothing to do with the volumes that Docker uses?

Furthermore, do volumes always have to be hosted on a docker container? I guess what I was expecting was that hosting providers removed a lot of the setup and let you create networks, volumes, containers while they managed the infrastructure and billed you for the resources you used. I don't think I can increase the size of the storage on the instance itself, it's locked to 20G on the package I'm on, but I can increase the volume. Is this the benefit of using the hosting provider's volume is that it can be increased as I need it?

Do volumes always have to be hosted on a docker container?

Am I understanding correctly the hosting provider's volume has nothing to do with the volumes that Docker uses?

Am I using docker appropriately? i.e. Am I doing anything outside of the norm that I should be doing differently?

答:
Docker volumes  are a Docker-specific construct that, as you're doing, are used to represent (file) storage used by containers (!). Volumes are similar to bind-mounts but are distinct.

Docker volumes are a unit of distribution for files that are available to containers (only). The concept of volumes appears often and refers to block (file) storage generally and is commonly used to refer to "disks" used by VMs. These concepts while similar are not transferable (VMs<-->containers).

Docker volumes are inextricably (!) bound to the host machine on which they're created. Unlike container images that may be pushed to and pulled from registries to move them between machines, volumes are unable to escape their creating host.

When you deploy your Docker (Compose?) solution to any other host (including those on cloud providers such as Digital Ocean), you must recreate the volumes you need on any of those remote hosts.

I'm unaware of any mechanism that facilitates moving volumes between machines as you need but it's entirely reasonable to want this functionality.

In the case of your e.g. database volume, the process by which you created that for your local host, must be replicated to create that volume on the remote host where you wish to access it even though you will be able to docker pull the database container image.

To answer your questions (as I understand them):

Volumes must be created on any Docker Engine (!) host where containers will be run that depend upon the volumes;

Correct: the concept of volumes is broadly applicable but, a cloud provider's concept of a volume will likely refer to some block (file) storage available to be used by VMs (not containers directly);

Your approach seems perfectly good. If you're not using Docker Compose, this may help in treating the containers and volumes as a unit (but Compose won't aid in moving solutions between hosts);

You are unable to use this but, by way of example, Kubernetes which is a popular complementary technology to Docker, includes a capability called Persistent Volumes that provides functionality similar to what you're seeking.


问:
Is it possible to base 36 encode with JavaScript / jQuery?
I'm thinking about using the encode/decode technique here (Encoding to base 36/decoding from base 36 is simple in Ruby)

how to implement a short url like urls in twitter?

Idea being to track user referrals, invite URLs. I can use Rails to decode, but it there a way to encode with Javascript or jQuery?

答:
I wrote this baseXY shortener, designed for a very similar question/need I had:

https://github.com/marko-36/base29-shortener.

By default, in order to leave out easily interchangeable characters, it is a base29 shortener, but the 'XY' number is the same as number of characters you decide to use for encoding.

Since the set of characters is fully customizable, you can omit any you wish (i, l, 1, L, o, 0, O..)

To make it less obvious, what the encoding character set is, and/or if you want the encoding string to have a minimal length, just start encoding from a high enough number.

This is it, hope it helps:

```<code>    const c=['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '2', '3', '4', '5', '6', '7', '8', '9'];
    //characters for encoding

    function to29(i){
        var sLen = Math.floor(Math.log(i)/Math.log(c.length)) +1;
        var s = '';
        for(ex=sLen-1; ex>-1; --ex){
            s += c[Math.floor(i / Math.pow(c.length,ex))];
            i = [i % Math.pow(c.length,ex)];
        }
        return s;
    }

    function from29(s){
        var i = 0;
        for (ex=0; ex<s.length; ++ex){
            i += c.indexOf(s.substring(ex,ex+1))*Math.pow(c.length,s.length-1-ex);
        }
        return i;
    }
</code>```

Body:
I wrote this baseXY shortener, designed for a very similar question/need I had:

https://github.com/marko-36/base29-shortener.

By default, in order to leave out easily interchangeable characters, it is a base29 shortener, but the 'XY' number is the same as number of characters you decide to use for encoding.

Since the set of characters is fully customizable, you can omit any you wish (i, l, 1, L, o, 0, O..)

To make it less obvious, what the encoding character set is, and/or if you want the encoding string to have a minimal length, just start encoding from a high enough number.

This is it, hope it helps:

    const c=['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '2', '3', '4', '5', '6', '7', '8', '9'];
    //characters for encoding

    function to29(i){
        var sLen = Math.floor(Math.log(i)/Math.log(c.length)) +1;
        var s = '';
        for(ex=sLen-1; ex>-1; --ex){
            s += c[Math.floor(i / Math.pow(c.length,ex))];
            i = [i % Math.pow(c.length,ex)];
        }
        return s;
    }

    function from29(s){
        var i = 0;
        for (ex=0; ex<s.length; ++ex){
            i += c.indexOf(s.substring(ex,ex+1))*Math.pow(c.length,s.length-1-ex);
        }
        return i;
    }


问:
'cv2' has no attribute 'transform'
I am trying to run the code suggested here by Harry R. (first solution to the question) and I get an error saying cv2 does not have transform method:

```<code>Traceback (most recent call last):
  File "/Users/kkk/PycharmProjects/TestICPPython3.7/ICPTest.py", line 64, in <module>
    M2 = icp(a, b, [0.1, 0.33, np.pi / 2.2], 30)
  File "/Users/kkk/PycharmProjects/TestICPPython3.7/ICPTest.py", line 32, in icp
    src = cv2.transform(src, Tr[0:2])
AttributeError: module 'cv2' has no attribute 'transform'
</code>```

Did anyone get this? What could be wrong? Thanks

答:
OK, I finally got this to work in Python 3.0 (I think the original version was Python 2.7) and not in Python 3.7. Note that there cv2.estimateRigidTransform is changed into cv2.estimateAffinePartial2D and we have two return variables instead of one in the original code since cv2.estimateRigidTransform is now eliminated.

```<code>import cv2
import numpy as np
import matplotlib.pyplot as plt
from sklearn.neighbors import NearestNeighbors

def icp(a, b, init_pose=(0, 0, 0), no_iterations=13):

    """
    The Iterative Closest Point estimator.
    Takes two cloudpoints a[x,y], b[x,y], an initial estimation of
    their relative pose and the number of iterations
    Returns the affine transform that transforms
    the cloudpoint a to the cloudpoint b.
    Note:
        (1) This method works for cloudpoints with minor
        transformations. Thus, the result depents greatly on
        the initial pose estimation.
        (2) A large number of iterations does not necessarily
        ensure convergence. Contrarily, most of the time it
        produces worse results.
    """

    src = np.array([a.T], copy=True).astype(np.float32)
    dst = np.array([b.T], copy=True).astype(np.float32)

    # Initialise with the initial pose estimation
    Tr = np.array([[np.cos(init_pose[2]), -np.sin(init_pose[2]), init_pose[0]],
                   [np.sin(init_pose[2]), np.cos(init_pose[2]), init_pose[1]],
                   [0, 0, 1]])

    src = cv2.transform(src, Tr[0:2])

    for i in range(no_iterations):

        # Find the nearest neighbours between the current source and the
        # destination cloudpoint

        nbrs = NearestNeighbors(n_neighbors=1, algorithm='auto').fit(dst[0])
        distances, indices = nbrs.kneighbors(src[0])

        # Compute the transformation between the current source
        # and destination cloudpoint
        T, tmp = cv2.estimateAffinePartial2D(src, dst[0, indices.T], False)
        # Transform the previous source and update the
        # current source cloudpoint
        src = cv2.transform(src, T)
        # Save the transformation from the actual source cloudpoint
        # to the destination
        Tr = np.dot(Tr, np.vstack((T, [0, 0, 1])))

    return Tr[0:2]

# Create the datasets
ang = np.linspace(-np.pi / 2, np.pi / 2, 320)
a = np.array([ang, np.sin(ang)])
th = np.pi / 2
rot = np.array([[np.cos(th), -np.sin(th)], [np.sin(th), np.cos(th)]])
b = np.dot(rot, a) + np.array([[0.2], [0.3]])

# Run the icp
M2 = icp(a, b, [0.1, 0.33, np.pi / 2.2], 30)
#
# # Plot the result
src = np.array([a.T]).astype(np.float32)
res = cv2.transform(src, M2)
plt.figure()
plt.plot(b[0], b[1])
plt.plot(res[0].T[0], res[0].T[1], 'r.')
plt.plot(a[0], a[1])
plt.show()
</code>```

Title: 'cv2' has no attribute 'transform'

Body:
I am trying to run the code suggested here by Harry R. (first solution to the question) and I get an error saying cv2 does not have transform method:

Traceback (most recent call last):
  File "/Users/kkk/PycharmProjects/TestICPPython3.7/ICPTest.py", line 64, in <module>
    M2 = icp(a, b, [0.1, 0.33, np.pi / 2.2], 30)
  File "/Users/kkk/PycharmProjects/TestICPPython3.7/ICPTest.py", line 32, in icp
    src = cv2.transform(src, Tr[0:2])
AttributeError: module 'cv2' has no attribute 'transform'

Did anyone get this? What could be wrong? Thanks

Body:
OK, I finally got this to work in Python 3.0 (I think the original version was Python 2.7) and not in Python 3.7. Note that there cv2.estimateRigidTransform is changed into cv2.estimateAffinePartial2D and we have two return variables instead of one in the original code since cv2.estimateRigidTransform is now eliminated.

import cv2
import numpy as np
import matplotlib.pyplot as plt
from sklearn.neighbors import NearestNeighbors

def icp(a, b, init_pose=(0, 0, 0), no_iterations=13):

    """
    The Iterative Closest Point estimator.
    Takes two cloudpoints a[x,y], b[x,y], an initial estimation of
    their relative pose and the number of iterations
    Returns the affine transform that transforms
    the cloudpoint a to the cloudpoint b.
    Note:
        (1) This method works for cloudpoints with minor
        transformations. Thus, the result depents greatly on
        the initial pose estimation.
        (2) A large number of iterations does not necessarily
        ensure convergence. Contrarily, most of the time it
        produces worse results.
    """

    src = np.array([a.T], copy=True).astype(np.float32)
    dst = np.array([b.T], copy=True).astype(np.float32)

    # Initialise with the initial pose estimation
    Tr = np.array([[np.cos(init_pose[2]), -np.sin(init_pose[2]), init_pose[0]],
                   [np.sin(init_pose[2]), np.cos(init_pose[2]), init_pose[1]],
                   [0, 0, 1]])

    src = cv2.transform(src, Tr[0:2])

    for i in range(no_iterations):

        # Find the nearest neighbours between the current source and the
        # destination cloudpoint

        nbrs = NearestNeighbors(n_neighbors=1, algorithm='auto').fit(dst[0])
        distances, indices = nbrs.kneighbors(src[0])

        # Compute the transformation between the current source
        # and destination cloudpoint
        T, tmp = cv2.estimateAffinePartial2D(src, dst[0, indices.T], False)
        # Transform the previous source and update the
        # current source cloudpoint
        src = cv2.transform(src, T)
        # Save the transformation from the actual source cloudpoint
        # to the destination
        Tr = np.dot(Tr, np.vstack((T, [0, 0, 1])))

    return Tr[0:2]

# Create the datasets
ang = np.linspace(-np.pi / 2, np.pi / 2, 320)
a = np.array([ang, np.sin(ang)])
th = np.pi / 2
rot = np.array([[np.cos(th), -np.sin(th)], [np.sin(th), np.cos(th)]])
b = np.dot(rot, a) + np.array([[0.2], [0.3]])

# Run the icp
M2 = icp(a, b, [0.1, 0.33, np.pi / 2.2], 30)
#
# # Plot the result
src = np.array([a.T]).astype(np.float32)
res = cv2.transform(src, M2)
plt.figure()
plt.plot(b[0], b[1])
plt.plot(res[0].T[0], res[0].T[1], 'r.')
plt.plot(a[0], a[1])
plt.show()


问:
Vue: How to use variable as array key in component binding
How can I use variable array keys for bindings in my custom component? In the following example, title must be 'Title 1 for default settings' if componenttype is set to 'default', 'Title 1 for guest settings' if componenttype is set to 'guest' etc. I tried to interpolate it in several ways, but nothing worked so far. Any hints?

```<code><my-component
    v-for="item in items"
    :id="item.id"
    :title="item['componenttype'].title"     <-- how to interpolate here?
>
</my-component>

...
data() {
   return {
      componenttype: 'default',
      items: [
         {
            1: {
               default: {
                  title: 'Title 1 for default settings',
               },
               guest: {
                  title: 'Title 1 for guest settings'
               }
            },
            2: {
               default: {
                  title: 'Title 2 for default settings',
               },
               guest: {
                  title: 'Title 2 for guest settings'
               }
            },
         }
      ]
   }
}
...
</code>```

答:
You are making componenttype into a string by doing :title="item['componenttype'].title".
Just do :title="item[componenttype].title"

Also check your array syntax, there might be some mistakes there

Body:
How can I use variable array keys for bindings in my custom component? In the following example, title must be 'Title 1 for default settings' if componenttype is set to 'default', 'Title 1 for guest settings' if componenttype is set to 'guest' etc. I tried to interpolate it in several ways, but nothing worked so far. Any hints?

<my-component
    v-for="item in items"
    :id="item.id"
    :title="item['componenttype'].title"     <-- how to interpolate here?
>
</my-component>

...
data() {
   return {
      componenttype: 'default',
      items: [
         {
            1: {
               default: {
                  title: 'Title 1 for default settings',
               },
               guest: {
                  title: 'Title 1 for guest settings'
               }
            },
            2: {
               default: {
                  title: 'Title 2 for default settings',
               },
               guest: {
                  title: 'Title 2 for guest settings'
               }
            },
         }
      ]
   }
}
...


问:
Detect message's name of sent image
I'm using a pokecord bot on my discord server, and I also have my own bot in the server. I want to make a feature, that when pokecord sends messageEmbed with pokemon spawn, my bot reacts to it. I tried the message.content.startsWith() method, but because it is messageEmbed, it isn't working. Is there some other way to do that? I was thinking, when you click on the pokemon picture, it opens in a new tab, called PokecordSpawn.jpg, maybe it could be done somehow in this way?

答:
You can check for the image file name in the MessageEmbed like so:

if (message.embeds) {
  if (message.embeds[0].image.url.includes('PokecordSpawn.jpg')) {
    // Do something
  }
}
```

You can also use message.embeds.forEach() in case the message has multiple embeds

Title: Detect message's name of sent image

Body:
You can check for the image file name in the MessageEmbed like so:

if (message.embeds) {
  if (message.embeds[0].image.url.includes('PokecordSpawn.jpg')) {
    // Do something
  }
}

You can also use message.embeds.forEach() in case the message has multiple embeds


问:
communication between micro-services after completed some thing
Let's say we have two microservices: MeetingProposal and Meeting.

Process of creating a meeting:

To create a meeting, users should propose their request, after their request, we create a proposal and show it to the admin.

If admin accepts the proposal then we should change the status of proposal to accepted and also create a meeting in the meeting microservice.

Question:

How we should connect these two processes to each other (after proposal accepted => create meeting automatically)?

答:
It's called business processes management, long running flows, sagas, or similar(see this)

We should use some orchestration engines like Cadence or Netflix Conductor or any other orchestration engine.


问:
How to call a composition function from another composition in VueJS
I've been experimenting with the new composition-api in VueJS and am not sure how to solve a problem. I'm looking for some advice on how to properly implement a solution. This wasn't a problem when everything was vuex-based since you can dispatch an action to another module without a problem. However, I'm struggling to find a solution for the composition implementation.

Problem:

Component calls a CompositionA's function.

CompositionA triggers a login function.

On CompositionA's login success/failure response I would like to call a CompositionB function. (CompositionB contains data and logic for showing a snackbar that's used across the site)

The problem is that it is necessary to inject the snackbar dependency in every component rather than have it be instantiated/mounted from CompositionA. Current solution is to this effect:

```<code>Component.vue:

// template calls login(credentials) method
import { useCompositionA } from '@/compositions/compositionA'
import { useCompositionB } from '@/compositions/compositionB'
export default {
  name: 'Component',
  setup(props, context) {
    const { login } = useCompositionA(props, context, useCompositionB(props, context))
    return {
      login
    }
  },
}

compositionA.js:

export const useAuth = (props, context, snack) => {
  const login = async (credentials) => {
    try {
      return await loginWithEmailPassword(credentials)
      snack.show({text: 'Welcome back!'})
    } catch (err) {
      snack.show({text: 'Failed to login'})
    }
  }
  return { login }
}

compositionB.js:

export const useSnack = (props, context) => {
  const snack = reactive({
    color: 'success',
    text: null,
    timeout: 6000,
    visible: true,
  })

  const snackRefs = toRefs(snack)

  const show = ({ text, timeout, color }) => {
    snackRefs.text.value = text
    snackRefs.timeout.value = timeout || 6000
    snackRefs.color.value = color || 'success'
    snackRefs.visible.value = true
  }
  return {
    ...snackRefs,
    show
  }
}
</code>```

Would be nice if something like below existed, but I'm finding that the properties aren't reactive in CompositionB if it's used from CompositionA (method gets called but snackbar doesn't show up). My understanding is that Vue isn't injecting CompositionB into the Component, so I'm just running another instance of CompositionB inside CompositionA. What am I doing something wrong? What's the proper solution here?

```<code>compositionA.js (not working):

import { useCompositionB } from '@/compositions/compositionB'
export const useAuth = (props, context) => {
  const login = async (credentials) => {
    const { show } = useCompositionB()
    try {
      return await loginWithEmailPassword(credentials)
      show({text: 'Welcome back!'})
    } catch (err) {
      show({text: 'Failed to login'})
    }
  }
  return { login }
}
</code>```

Thanks in advance,

答:
As expected it was due to the Component referencing its own local copy of CompositionB*. Solution is actually to bring the state of your compositions into the global scope according to:

https://vueschool.io/articles/vuejs-tutorials/state-management-with-composition-api/

Something like this:

```<code>compositionB.js:

const snack = reactive({
  color: 'success',
  text: null,
  timeout: 6000,
  visible: true,
})
export const useSnack = (props, context) => {

  const snackRefs = toRefs(snack)

  const show = ({ text, timeout, color }) => {
    snackRefs.text.value = text
    snackRefs.timeout.value = timeout || 6000
    snackRefs.color.value = color || 'success'
    snackRefs.visible.value = true
  }
  return {
    ...snackRefs,
    show
  }
}
</code>```

Works like a charm.

Only caveat I found initially was a composition-api error:

```<code>Uncaught Error: [vue-composition-api] must call Vue.use(plugin) before using any function.
</code>```

This was easily solved by mounting the composition-api first thing in main.js as per solution here:

Uncaught Error: [vue-composition-api] must call Vue.use(plugin) before using any function

I think this won't be a problem with vue3 comes out. Hope this helps someone.

Body:
I've been experimenting with the new composition-api in VueJS and am not sure how to solve a problem. I'm looking for some advice on how to properly implement a solution. This wasn't a problem when everything was vuex-based since you can dispatch an action to another module without a problem. However, I'm struggling to find a solution for the composition implementation.

Problem:

Component calls a CompositionA's function.

CompositionA triggers a login function.

On CompositionA's login success/failure response I would like to call a CompositionB function. (CompositionB contains data and logic for showing a snackbar that's used across the site)

The problem is that it is necessary to inject the snackbar dependency in every component rather than have it be instantiated/mounted from CompositionA. Current solution is to this effect:

Component.vue:

// template calls login(credentials) method
import { useCompositionA } from '@/compositions/compositionA'
import { useCompositionB } from '@/compositions/compositionB'
export default {
  name: 'Component',
  setup(props, context) {
    const { login } = useCompositionA(props, context, useCompositionB(props, context))
    return {
      login
    }
  },
}

compositionA.js:

export const useAuth = (props, context, snack) => {
  const login = async (credentials) => {
    try {
      return await loginWithEmailPassword(credentials)
      snack.show({text: 'Welcome back!'})
    } catch (err) {
      snack.show({text: 'Failed to login'})
    }
  }
  return { login }
}

compositionB.js:

export const useSnack = (props, context) => {
  const snack = reactive({
    color: 'success',
    text: null,
    timeout: 6000,
    visible: true,
  })

  const snackRefs = toRefs(snack)

  const show = ({ text, timeout, color }) => {
    snackRefs.text.value = text
    snackRefs.timeout.value = timeout || 6000
    snackRefs.color.value = color || 'success'
    snackRefs.visible.value = true
  }
  return {
    ...snackRefs,
    show
  }
}

Would be nice if something like below existed, but I'm finding that the properties aren't reactive in CompositionB if it's used from CompositionA (method gets called but snackbar doesn't show up). My understanding is that Vue isn't injecting CompositionB into the Component, so I'm just running another instance of CompositionB inside CompositionA. What am I doing something wrong? What's the proper solution here?

compositionA.js (not working):

import { useCompositionB } from '@/compositions/compositionB'
export const useAuth = (props, context) => {
  const login = async (credentials) => {
    const { show } = useCompositionB()
    try {
      return await loginWithEmailPassword(credentials)
      show({text: 'Welcome back!'})
    } catch (err) {
      show({text: 'Failed to login'})
    }
  }
  return { login }
}

Thanks in advance,

Body:
As expected it was due to the Component referencing its own local copy of CompositionB*. Solution is actually to bring the state of your compositions into the global scope according to:

https://vueschool.io/articles/vuejs-tutorials/state-management-with-composition-api/

Something like this:

compositionB.js:

const snack = reactive({
  color: 'success',
  text: null,
  timeout: 6000,
  visible: true,
})
export const useSnack = (props, context) => {

  const snackRefs = toRefs(snack)

  const show = ({ text, timeout, color }) => {
    snackRefs.text.value = text
    snackRefs.timeout.value = timeout || 6000
    snackRefs.color.value = color || 'success'
    snackRefs.visible.value = true
  }
  return {
    ...snackRefs,
    show
  }
}

Works like a charm.

Only caveat I found initially was a composition-api error:

Uncaught Error: [vue-composition-api] must call Vue.use(plugin) before using any function.

This was easily solved by mounting the composition-api first thing in main.js as per solution here:

Uncaught Error: [vue-composition-api] must call Vue.use(plugin) before using any function

I think this won't be a problem with vue3 comes out. Hope this helps someone.


问:
401 error accessing Cloudant from IBM Cloud Function
I have created a Cloudant service and credentials (1) along with a database and a couple of documents. I want to access that database from an IBM Cloud Function so created a function to do that. I tested the function by adding the copied and pasted credentials from (1) into the "Invoke with credentials" box (along with the and the db name and a valid docid). The function seems to take all that info correctly but I get a 401 error... any help would be massively appreciated!

```<code>{
  "error": {
    "description": "couch returned 401",
    "errid": "non_200",
    "error": "unauthorized",
    "headers": {
      "cache-control": "must-revalidate",
      "content-type": "application/json",
      "date": "Sat, 30 May 2020 16:37:25 GMT",
      "statusCode": 401,
      "strict-transport-security": "max-age=31536000",
      "uri": "xxxxxxx",
      "via": "1.1 lb1.bm-cc-eu-gb-04 (Glum/1.89.6)",
      "www-authenticate": "Basic realm=\"Cloudant Private Database\"",
      "x-cloudant-action": "cloudantnosqldb.any-document.read",
      "x-cloudant-backend": "bm-cc-eu-gb-04",
      "x-cloudant-request-class": "lookup",
      "x-content-type-options": "nosniff",
      "x-couch-request-id": "03e7fe91bb"
    },
    "message": "_reader access is required for this request",
    "name": "Error",
    "reason": "_reader access is required for this request",
    "request": {
      "headers": {
        "accept": "application/json",
        "content-type": "application/json"
      },
      "method": "GET",
      "uri": "xxxxx"
    },
    "scope": "couch",
    "stack": "Error: _reader access is required for this request\n    at Object.clientCallback (/node_modules/@cloudant/cloudant/node_modules/nano/lib/nano.js:151:15)\n    at Request._callback (/node_modules/@cloudant/cloudant/lib/clientutils.js:162:11)\n    at Request.self.callback (/node_modules/request/request.js:185:22)\n    at Request.emit (events.js:198:13)\n    at Request.self._source.emit (/node_modules/@cloudant/cloudant/lib/eventrelay.js:78:21)\n    at Request.<anonymous> (/node_modules/request/request.js:1161:10)\n    at Request.emit (events.js:198:13)\n    at Request.self._source.emit (/node_modules/@cloudant/cloudant/lib/eventrelay.js:78:21)\n    at IncomingMessage.<anonymous> (/node_modules/request/request.js:1083:12)",
    "statusCode": 401
  }
}
</code>```

The function code is as follows:

```<code>/**
 * Read a document in Cloudant database:
 * https://docs.cloudant.com/document.html#read
 **/

function main(message) {

    var cloudantOrError = getCloudantAccount(message);
    if (typeof cloudantOrError !== 'object') {
        return Promise.reject(cloudantOrError);
    }
    var cloudant = cloudantOrError;

    var dbName = message.dbname;
    var docId = message.docid || message.id;
    var params = {};

    if (!dbName) {
        return Promise.reject('dbname is required.');
    }
    if (!docId) {
        return Promise.reject('docid is required.');
    }
    var cloudantDb = cloudant.use(dbName);

    if (typeof message.params === 'object') {
        params = message.params;
    } else if (typeof message.params === 'string') {
        try {
            params = JSON.parse(message.params);
        } catch (e) {
            return Promise.reject('params field cannot be parsed. Ensure it is valid JSON.');
        }
    }

    return readDocument(cloudantDb, docId, params);
}

function readDocument(cloudantDb, docId, params) {
    return new Promise(function (resolve, reject) {
        cloudantDb.get(docId, params, function (error, response) {
            if (!error) {
                resolve(response);
            } else {
                console.error('error', error);
                reject(error);
            }
        });
    });
}

function getCloudantAccount(params) {

    var Cloudant = require('@cloudant/cloudant');
    var cloudant;

    if (!params.iamApiKey && params.url) {
        cloudant = Cloudant(params.url);
    } else {
        checkForBXCreds(params);

        if (!params.host) {
            return 'Cloudant account host is required.';
        }

        if (!params.iamApiKey) {
            if (!params.username || !params.password) {
                return 'You must specify parameter/s of iamApiKey or username/password';
            }
        }

        var protocol = params.protocol || 'https';
        if (params.iamApiKey) {
            var dbURL = `${protocol}://${params.host}`;
            if (params.port) {
                dbURL += ':' + params.port;
            }
            cloudant = new Cloudant({
                url: dbURL,
                plugins: {iamauth: {iamApiKey: params.iamApiKey, iamTokenUrl: params.iamUrl}}
            });
        } else {
            var url = `${protocol}://${params.username}:${params.password}@${params.host}`;
            if (params.port) {
                url += ':' + params.port;
            }
            cloudant = Cloudant(url);
        }
    }
    return cloudant;
}

function checkForBXCreds(params) {

    if (params.__bx_creds && (params.__bx_creds.cloudantnosqldb || params.__bx_creds.cloudantNoSQLDB)) {
        var cloudantCreds = params.__bx_creds.cloudantnosqldb || params.__bx_creds.cloudantNoSQLDB;

        if (!params.host) {
            params.host = cloudantCreds.host || (cloudantCreds.username + '.cloudant.com');
        }
        if (!params.iamApiKey && !cloudantCreds.apikey) {
            if (!params.username) {
                params.username = cloudantCreds.username;
            }
            if (!params.password) {
                params.password = cloudantCreds.password;
            }
        } else if (!params.iamApiKey) {
            params.iamApiKey = cloudantCreds.apikey;
        }
    }

}
</code>```

答: Basically, copying and pasting those credentials led to it not working. Not sure why. To get a test invocation working I added url, docid, dbname, host, url and iamApiKey values to the parameters section of the function. That worked.</p>

Body:
I have created a Cloudant service and credentials (1) along with a database and a couple of documents. I want to access that database from an IBM Cloud Function so created a function to do that. I tested the function by adding the copied and pasted credentials from (1) into the "Invoke with credentials" box (along with the and the db name and a valid docid). The function seems to take all that info correctly but I get a 401 error... any help would be massively appreciated!

{
  "error": {
    "description": "couch returned 401",
    "errid": "non_200",
    "error": "unauthorized",
    "headers": {
      "cache-control": "must-revalidate",
      "content-type": "application/json",
      "date": "Sat, 30 May 2020 16:37:25 GMT",
      "statusCode": 401,
      "strict-transport-security": "max-age=31536000",
      "uri": "xxxxxxx",
      "via": "1.1 lb1.bm-cc-eu-gb-04 (Glum/1.89.6)",
      "www-authenticate": "Basic realm=\"Cloudant Private Database\"",
      "x-cloudant-action": "cloudantnosqldb.any-document.read",
      "x-cloudant-backend": "bm-cc-eu-gb-04",
      "x-cloudant-request-class": "lookup",
      "x-content-type-options": "nosniff",
      "x-couch-request-id": "03e7fe91bb"
    },
    "message": "_reader access is required for this request",
    "name": "Error",
    "reason": "_reader access is required for this request",
    "request": {
      "headers": {
        "accept": "application/json",
        "content-type": "application/json"
      },
      "method": "GET",
      "uri": "xxxxx"
    },
    "scope": "couch",
    "stack": "Error: _reader access is required for this request\n    at Object.clientCallback (/node_modules/@cloudant/cloudant/node_modules/nano/lib/nano.js:151:15)\n    at Request._callback (/node_modules/@cloudant/cloudant/lib/clientutils.js:162:11)\n    at Request.self.callback (/node_modules/request/request.js:185:22)\n    at Request.emit (events.js:198:13)\n    at Request.self._source.emit (/node_modules/@cloudant/cloudant/lib/eventrelay.js:78:21)\n    at Request.<anonymous> (/node_modules/request/request.js:1161:10)\n    at Request.emit (events.js:198:13)\n    at Request.self._source.emit (/node_modules/@cloudant/cloudant/lib/eventrelay.js:78:21)\n    at IncomingMessage.<anonymous> (/node_modules/request/request.js:1083:12)",
    "statusCode": 401
  }
}

The function code is as follows:

/**
 * Read a document in Cloudant database:
 * https://docs.cloudant.com/document.html#read
 **/

function main(message) {

    var cloudantOrError = getCloudantAccount(message);
    if (typeof cloudantOrError !== 'object') {
        return Promise.reject(cloudantOrError);
    }
    var cloudant = cloudantOrError;

    var dbName = message.dbname;
    var docId = message.docid || message.id;
    var params = {};

    if (!dbName) {
        return Promise.reject('dbname is required.');
    }
    if (!docId) {
        return Promise.reject('docid is required.');
    }
    var cloudantDb = cloudant.use(dbName);

    if (typeof message.params === 'object') {
        params = message.params;
    } else if (typeof message.params === 'string') {
        try {
            params = JSON.parse(message.params);
        } catch (e) {
            return Promise.reject('params field cannot be parsed. Ensure it is valid JSON.');
        }
    }

    return readDocument(cloudantDb, docId, params);
}

function readDocument(cloudantDb, docId, params) {
    return new Promise(function (resolve, reject) {
        cloudantDb.get(docId, params, function (error, response) {
            if (!error) {
                resolve(response);
            } else {
                console.error('error', error);
                reject(error);
            }
        });
    });
}

function getCloudantAccount(params) {

    var Cloudant = require('@cloudant/cloudant');
    var cloudant;

    if (!params.iamApiKey && params.url) {
        cloudant = Cloudant(params.url);
    } else {
        checkForBXCreds(params);

        if (!params.host) {
            return 'Cloudant account host is required.';
        }

        if (!params.iamApiKey) {
            if (!params.username || !params.password) {
                return 'You must specify parameter/s of iamApiKey or username/password';
            }
        }

        var protocol = params.protocol || 'https';
        if (params.iamApiKey) {
            var dbURL = `${protocol}://${params.host}`;
            if (params.port) {
                dbURL += ':' + params.port;
            }
            cloudant = new Cloudant({
                url: dbURL,
                plugins: {iamauth: {iamApiKey: params.iamApiKey, iamTokenUrl: params.iamUrl}}
            });
        } else {
            var url = `${protocol}://${params.username}:${params.password}@${params.host}`;
            if (params.port) {
                url += ':' + params.port;
            }
            cloudant = Cloudant(url);
        }
    }
    return cloudant;
}

function checkForBXCreds(params) {

    if (params.__bx_creds && (params.__bx_creds.cloudantnosqldb || params.__bx_creds.cloudantNoSQLDB)) {
        var cloudantCreds = params.__bx_creds.cloudantnosqldb || params.__bx_creds.cloudantNoSQLDB;

        if (!params.host) {
            params.host = cloudantCreds.host || (cloudantCreds.username + '.cloudant.com');
        }
        if (!params.iamApiKey && !cloudantCreds.apikey) {
            if (!params.username) {
                params.username = cloudantCreds.username;
            }
            if (!params.password) {
                params.password = cloudantCreds.password;
            }
        } else if (!params.iamApiKey) {
            params.iamApiKey = cloudantCreds.apikey;
        }
    }

}


问:
C# Generic method for random number generation
I see that there is a similar question for C++. Does anyone know why this method works when the method is non-generic, but as soon as I make it generic, the random number portion of code fails?
Error: Cannot implicitly convert type int to 'T'. If I can't use generics, I will have to rewrite the same function over and over for each different length of array. </p>

```<code>public void fillGenericArray<T>(T[] inputArray) where T : IComparable
{
    var randomNumb1 = new Random();

    for (int i = 0; i < inputArray.Length - 1; i++)
    {
        Console.WriteLine($"{inputArray[i] = randomNumb1.Next(1, 501)},");
    }
}
</code>```

答:
There is no reason to use generics. Just replace T with int and you will have function that does what you want (based on your question and comment below it).

EDIT: From your comment it seems you misunderstand the purpose of generics. The non-generic function WILL work for all lengths of the array.

And to answer why the change to generics fails. You are trying to assign int to generic type T which can be anything and compiler will not allow such a cast.

Body:
I see that there is a similar question for C++. Does anyone know why this method works when the method is non-generic, but as soon as I make it generic, the random number portion of code fails?
Error: Cannot implicitly convert type int to 'T'. If I can't use generics, I will have to rewrite the same function over and over for each different length of array.

public void fillGenericArray<T>(T[] inputArray) where T : IComparable
{
    var randomNumb1 = new Random();

    for (int i = 0; i < inputArray.Length - 1; i++)
    {
        Console.WriteLine($"{inputArray[i] = randomNumb1.Next(1, 501)},");
    }
}