问:
Docker build Fails when trying to install Fiona using python image
I want to build a Docker container with a Python Dash App. The app requires geospatial packages like Geopandas, Folium, Shapely. When trying to build the Docker Image it fails when trying to install Fiona, it says it requires GDAL. I don't know exacly how to install the gdal package to the base image.

Dockerfile

```<code>FROM python:3.8-slim
WORKDIR /code
COPY ./requirements.txt /code/requirements.txt
RUN pip install -r requirements.txt && rm -rf /root/.cache
COPY ./ /code/
CMD ["gunicorn","-b","0.0.0.0:8080","index:server"]
</code>```

requirements.txt

```<code>attrs==21.2.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.7"
branca==0.4.2; python_version >= "3.5"
brotli==1.0.9; python_version >= "3.6"
certifi==2021.10.8; python_version >= "3.8" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.8"
charset-normalizer==2.0.10; python_full_version >= "3.6.0" and python_version >= "3.5"
chart-studio==1.1.0
click-plugins==1.1.1; python_version >= "3.7"
click==8.0.3; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version < "4" and python_version >= "3.7"
cligj==0.7.2; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version < "4" and python_version >= "3.7"
colorama==0.4.4; python_version >= "3.7" and python_full_version < "3.0.0" and platform_system == "Windows" or platform_system == "Windows" and python_version >= "3.7" and python_full_version >= "3.5.0"
cycler==0.11.0; python_version >= "3.7"
dash-auth==1.4.1
dash-bootstrap-components==1.0.0; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.5.0" and python_version < "4")
dash-core-components==2.0.0; python_version >= "3.6"
dash-daq==0.5.0
dash-html-components==2.0.0; python_version >= "3.6"
dash-table==5.0.0; python_version >= "3.6"
dash==2.0.0; python_version >= "3.6"
fiona==1.8.20; python_version >= "3.7"
flask-compress==1.10.1; python_version >= "3.6"
flask-seasurf==0.3.1
flask==2.0.2; python_version >= "3.6"
folium==0.12.1.post1; python_version >= "3.5"
fonttools==4.29.1; python_version >= "3.7"
geopandas==0.10.2; python_version >= "3.7"
gunicorn==20.1.0; python_version >= "3.5"
idna==3.3; python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.5"
itsdangerous==2.0.1; python_version >= "3.6"
jinja2==3.0.3; python_version >= "3.6"
joblib==1.1.0; python_version >= "3.7"
kiwisolver==1.3.2; python_version >= "3.7"
mapclassify==2.4.3
markupsafe==2.0.1; python_version >= "3.6"
matplotlib==3.5.1; python_version >= "3.7"
munch==2.5.0; python_version >= "3.7"
networkx==2.6.3; python_version >= "3.7"
numpy==1.21.1; python_version >= "3.7"
packaging==21.3; python_version >= "3.7"
pandas==1.3.4; python_full_version >= "3.7.1"
pillow==9.0.1; python_version >= "3.7"
plotly==5.4.0; python_version >= "3.6"
pyparsing==3.0.7; python_version >= "3.7"
pyproj==3.3.0; python_version >= "3.8"
python-dateutil==2.8.2; python_full_version >= "3.7.1" and python_version >= "3.7"
python-decouple==3.5
pytz==2021.3; python_full_version >= "3.7.1" and python_version >= "3.7"
requests==2.27.1; python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.5"
retrying==1.3.3
rtree==0.9.7
scikit-learn==1.0.2; python_version >= "3.7"
scipy==1.6.1; python_version >= "3.7"
setuptools-scm==6.4.2; python_version >= "3.7"
shapely==1.8.0; python_version >= "3.7"
six==1.16.0; python_full_version >= "3.7.1" and python_version >= "3.7" and (python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version >= "3.6") and (python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.3.0") and (python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version >= "3.7")
tenacity==8.0.1; python_version >= "3.6"
threadpoolctl==3.1.0; python_version >= "3.7"
tomli==2.0.0; python_version >= "3.7"
ua-parser==0.10.0
urllib3==1.26.8; python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version < "4" and python_version >= "3.5"
werkzeug==2.0.2; python_version >= "3.6"
</code>```

Result when trying to build

```<code>...
#8 2.723   Downloading dash_table-5.0.0.tar.gz (3.4 kB)
#8 2.843 Collecting dash==2.0.0
#8 2.859   Downloading dash-2.0.0-py3-none-any.whl (7.3 MB)
#8 3.850 Collecting fiona==1.8.20
#8 3.882   Downloading Fiona-1.8.20.tar.gz (1.3 MB)
#8 4.187     ERROR: Command errored out with exit status 1:
#8 4.187      command: /usr/local/bin/python -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-bsxe9wyf/fiona_029030bfc6284bc292763bed2693d299/setup.py'"'"'; __file__='"'"'/tmp/pip-install-bsxe9wyf/fiona_029030bfc6284bc292763bed2693d299/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pip-pip-egg-info-oim_g79k
#8 4.187          cwd: /tmp/pip-install-bsxe9wyf/fiona_029030bfc6284bc292763bed2693d299/
#8 4.187     Complete output (2 lines):
#8 4.187     Failed to get options via gdal-config: [Errno 2] No such file or directory: 'gdal-config'
#8 4.187     A GDAL API version must be specified. Provide a path to gdal-config using a GDAL_CONFIG environment variable or use a GDAL_VERSION environment variable.
#8 4.187     ----------------------------------------
#8 4.187 WARNING: Discarding https://files.pythonhosted.org/packages/ec/f7/093890341a7e8fbfcdfa04caf4dfb588ebab32c13ceaa6a3819da79ea106/Fiona-1.8.20.tar.gz#sha256=a70502d2857b82f749c09cb0dea3726787747933a2a1599b5ab787d74e3c143b (from https://pypi.org/simple/fiona/). Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
#8 4.188 ERROR: Could not find a version that satisfies the requirement fiona==1.8.20 (from versions: 0.5, 0.6, 0.6.1, 0.6.2, 0.7, 0.8, 0.9, 0.9.1, 0.10, 0.12, 0.12.1, 0.13, 0.14, 0.15, 0.16, 0.16.1, 1.0, 1.0.1, 1.0.2, 1.0.3, 1.1, 1.1.1, 1.1.2, 1.1.3, 1.1.4, 1.1.5, 1.1.6, 1.2.0, 1.3.0, 1.4.0, 1.4.1, 1.4.2, 1.4.3, 1.4.4, 1.4.5, 1.4.6, 1.4.7, 1.4.8, 1.5.0, 1.5.1, 1.6.0, 1.6.1, 1.6.2, 1.6.3, 1.6.3.post1, 1.6.4, 1.7b1, 1.7.0, 1.7.0.post2, 1.7.1, 1.7.1.post1, 1.7.2, 1.7.3, 1.7.4, 1.7.5, 1.7.6, 1.7.7, 1.7.8, 1.7.9, 1.7.9.post1, 1.7.10, 1.7.10.post1, 1.7.11, 1.7.11.post1, 1.7.11.post2, 1.7.12, 1.7.13, 1.8a1, 1.8a2, 1.8a3, 1.8b1, 1.8b2, 1.8rc1, 1.8.0, 1.8.1, 1.8.2, 1.8.3, 1.8.4, 1.8.5, 1.8.6, 1.8.7, 1.8.8, 1.8.9, 1.8.9.post1, 1.8.9.post2, 1.8.10, 1.8.11, 1.8.12, 1.8.13, 1.8.13.post1, 1.8.14, 1.8.15, 1.8.16, 1.8.17, 1.8.18, 1.8.19, 1.8.20, 1.8.21)
#8 4.188 ERROR: No matching distribution found for fiona==1.8.20
#8 4.252 WARNING: You are using pip version 21.2.4; however, version 22.0.3 is available.
#8 4.252 You should consider upgrading via the '/usr/local/bin/python -m pip install --upgrade pip' command.
------
executor failed running [/bin/sh -c pip install -r requirements.txt && rm -rf /root/.cache]: exit code: 1
</code>```

I appreciate any help to build this image successfully.

答:
My guess is that adding this before requirements installation may help

```<code>RUN apt-get install gdal-bin
</code>```

I am not sure if that's the right command to install GDAL. If it isn't, just look up how to install it and add it to your dockerfile.

Body:
I want to build a Docker container with a Python Dash App. The app requires geospatial packages like Geopandas, Folium, Shapely. When trying to build the Docker Image it fails when trying to install Fiona, it says it requires GDAL. I don't know exacly how to install the gdal package to the base image.

Dockerfile

FROM python:3.8-slim
WORKDIR /code
COPY ./requirements.txt /code/requirements.txt
RUN pip install -r requirements.txt && rm -rf /root/.cache
COPY ./ /code/
CMD ["gunicorn","-b","0.0.0.0:8080","index:server"]

requirements.txt

attrs==21.2.0; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.7"
branca==0.4.2; python_version >= "3.5"
brotli==1.0.9; python_version >= "3.6"
certifi==2021.10.8; python_version >= "3.8" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.8"
charset-normalizer==2.0.10; python_full_version >= "3.6.0" and python_version >= "3.5"
chart-studio==1.1.0
click-plugins==1.1.1; python_version >= "3.7"
click==8.0.3; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version < "4" and python_version >= "3.7"
cligj==0.7.2; python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version < "4" and python_version >= "3.7"
colorama==0.4.4; python_version >= "3.7" and python_full_version < "3.0.0" and platform_system == "Windows" or platform_system == "Windows" and python_version >= "3.7" and python_full_version >= "3.5.0"
cycler==0.11.0; python_version >= "3.7"
dash-auth==1.4.1
dash-bootstrap-components==1.0.0; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.5.0" and python_version < "4")
dash-core-components==2.0.0; python_version >= "3.6"
dash-daq==0.5.0
dash-html-components==2.0.0; python_version >= "3.6"
dash-table==5.0.0; python_version >= "3.6"
dash==2.0.0; python_version >= "3.6"
fiona==1.8.20; python_version >= "3.7"
flask-compress==1.10.1; python_version >= "3.6"
flask-seasurf==0.3.1
flask==2.0.2; python_version >= "3.6"
folium==0.12.1.post1; python_version >= "3.5"
fonttools==4.29.1; python_version >= "3.7"
geopandas==0.10.2; python_version >= "3.7"
gunicorn==20.1.0; python_version >= "3.5"
idna==3.3; python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.5"
itsdangerous==2.0.1; python_version >= "3.6"
jinja2==3.0.3; python_version >= "3.6"
joblib==1.1.0; python_version >= "3.7"
kiwisolver==1.3.2; python_version >= "3.7"
mapclassify==2.4.3
markupsafe==2.0.1; python_version >= "3.6"
matplotlib==3.5.1; python_version >= "3.7"
munch==2.5.0; python_version >= "3.7"
networkx==2.6.3; python_version >= "3.7"
numpy==1.21.1; python_version >= "3.7"
packaging==21.3; python_version >= "3.7"
pandas==1.3.4; python_full_version >= "3.7.1"
pillow==9.0.1; python_version >= "3.7"
plotly==5.4.0; python_version >= "3.6"
pyparsing==3.0.7; python_version >= "3.7"
pyproj==3.3.0; python_version >= "3.8"
python-dateutil==2.8.2; python_full_version >= "3.7.1" and python_version >= "3.7"
python-decouple==3.5
pytz==2021.3; python_full_version >= "3.7.1" and python_version >= "3.7"
requests==2.27.1; python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.5"
retrying==1.3.3
rtree==0.9.7
scikit-learn==1.0.2; python_version >= "3.7"
scipy==1.6.1; python_version >= "3.7"
setuptools-scm==6.4.2; python_version >= "3.7"
shapely==1.8.0; python_version >= "3.7"
six==1.16.0; python_full_version >= "3.7.1" and python_version >= "3.7" and (python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version >= "3.6") and (python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.3.0") and (python_version >= "3.7" and python_full_version < "3.0.0" or python_full_version >= "3.3.0" and python_version >= "3.7")
tenacity==8.0.1; python_version >= "3.6"
threadpoolctl==3.1.0; python_version >= "3.7"
tomli==2.0.0; python_version >= "3.7"
ua-parser==0.10.0
urllib3==1.26.8; python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version < "4" and python_version >= "3.5"
werkzeug==2.0.2; python_version >= "3.6"

Result when trying to build

...
#8 2.723   Downloading dash_table-5.0.0.tar.gz (3.4 kB)
#8 2.843 Collecting dash==2.0.0
#8 2.859   Downloading dash-2.0.0-py3-none-any.whl (7.3 MB)
#8 3.850 Collecting fiona==1.8.20
#8 3.882   Downloading Fiona-1.8.20.tar.gz (1.3 MB)
#8 4.187     ERROR: Command errored out with exit status 1:
#8 4.187      command: /usr/local/bin/python -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-bsxe9wyf/fiona_029030bfc6284bc292763bed2693d299/setup.py'"'"'; __file__='"'"'/tmp/pip-install-bsxe9wyf/fiona_029030bfc6284bc292763bed2693d299/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pip-pip-egg-info-oim_g79k
#8 4.187          cwd: /tmp/pip-install-bsxe9wyf/fiona_029030bfc6284bc292763bed2693d299/
#8 4.187     Complete output (2 lines):
#8 4.187     Failed to get options via gdal-config: [Errno 2] No such file or directory: 'gdal-config'
#8 4.187     A GDAL API version must be specified. Provide a path to gdal-config using a GDAL_CONFIG environment variable or use a GDAL_VERSION environment variable.
#8 4.187     ----------------------------------------
#8 4.187 WARNING: Discarding https://files.pythonhosted.org/packages/ec/f7/093890341a7e8fbfcdfa04caf4dfb588ebab32c13ceaa6a3819da79ea106/Fiona-1.8.20.tar.gz#sha256=a70502d2857b82f749c09cb0dea3726787747933a2a1599b5ab787d74e3c143b (from https://pypi.org/simple/fiona/). Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
#8 4.188 ERROR: Could not find a version that satisfies the requirement fiona==1.8.20 (from versions: 0.5, 0.6, 0.6.1, 0.6.2, 0.7, 0.8, 0.9, 0.9.1, 0.10, 0.12, 0.12.1, 0.13, 0.14, 0.15, 0.16, 0.16.1, 1.0, 1.0.1, 1.0.2, 1.0.3, 1.1, 1.1.1, 1.1.2, 1.1.3, 1.1.4, 1.1.5, 1.1.6, 1.2.0, 1.3.0, 1.4.0, 1.4.1, 1.4.2, 1.4.3, 1.4.4, 1.4.5, 1.4.6, 1.4.7, 1.4.8, 1.5.0, 1.5.1, 1.6.0, 1.6.1, 1.6.2, 1.6.3, 1.6.3.post1, 1.6.4, 1.7b1, 1.7.0, 1.7.0.post2, 1.7.1, 1.7.1.post1, 1.7.2, 1.7.3, 1.7.4, 1.7.5, 1.7.6, 1.7.7, 1.7.8, 1.7.9, 1.7.9.post1, 1.7.10, 1.7.10.post1, 1.7.11, 1.7.11.post1, 1.7.11.post2, 1.7.12, 1.7.13, 1.8a1, 1.8a2, 1.8a3, 1.8b1, 1.8b2, 1.8rc1, 1.8.0, 1.8.1, 1.8.2, 1.8.3, 1.8.4, 1.8.5, 1.8.6, 1.8.7, 1.8.8, 1.8.9, 1.8.9.post1, 1.8.9.post2, 1.8.10, 1.8.11, 1.8.12, 1.8.13, 1.8.13.post1, 1.8.14, 1.8.15, 1.8.16, 1.8.17, 1.8.18, 1.8.19, 1.8.20, 1.8.21)
#8 4.188 ERROR: No matching distribution found for fiona==1.8.20
#8 4.252 WARNING: You are using pip version 21.2.4; however, version 22.0.3 is available.
#8 4.252 You should consider upgrading via the '/usr/local/bin/python -m pip install --upgrade pip' command.
------
executor failed running [/bin/sh -c pip install -r requirements.txt && rm -rf /root/.cache]: exit code: 1

I appreciate any help to build this image successfully.

Body:
My guess is that adding this before requirements installation may help

RUN apt-get install gdal-bin

I am not sure if that's the right command to install GDAL. If it isn't, just look up how to install it and add it to your dockerfile.


来源: stackexchange

问:
TRANSFORM COLUMN IN ROW AND CONCATENATE
I have a DF and I want to do two transformations: (i) row to column and (ii) concatenate columns. This is my DF:

```<code>CAR <- c('BMW','BMW','BMW','FERRARI','FERRARI','VW')
DATE <- c('OCT','NOV','DEC','OCT','DEC','DEC')
TIME <- c(10,12,15,7,11,14)
QUANTITY <- c(115,101,95,88,130,101)
DF <- data.frame(CAR,DATA,TIME,QUANTITY)
</code>```

I want to transform into this DF2:

```<code>CAR <- c('BMW','FERRARI','VW')
OCT <- c('10 N=(115)','7 N=(88)',' N=()')
NOV <- c('12 N=(101)',' N=()',' N=()')
DEC <- c('15 N=(95)','11 N=(130)','14 N=(101)')
DF2 <- data.frame(CAR,OCT,NOV,DEC)
</code>```

See that the contents of the DATA column turned into 3 columns. Also, I concatenated TIME and QUANTITY, but included the letter “N” and the parentheses. Is this kind of transformation possible?

答:
We may use sprintf/glue to format the columns and then reshape with pivot_wider

```<code>library(dplyr)
library(tidyr)
DF %>%
    mutate(TIMEQ = sprintf('%d N=(%d)', TIME, QUANTITY), .keep = 'unused') %>%
    pivot_wider(names_from = DATE, values_from = TIMEQ)
</code>```

By default, if the combination is missing, it returns NA, but if we want to fill with a custom value, use values_fill

```<code>DF %>%
    mutate(TIMEQ = sprintf('%d N=(%d)', TIME, QUANTITY), .keep = 'unused') %>%
    pivot_wider(names_from = DATE, values_from = TIMEQ, values_fill = "N=())
</code>```

-output

```<code># A tibble: 3 × 4
  CAR     OCT        NOV        DEC
  <chr>   <chr>      <chr>      <chr>
1 BMW     10 N=(115) 12 N=(101) 15 N=(95)
2 FERRARI 7 N=(88)   N=()       11 N=(130)
3 VW      N=()       N=()       14 N=(101)
</code>```

ContentLicense: CC BY-SA 4.0

Title: TRANSFORM COLUMN IN ROW AND CONCATENATE

Body:
I have a DF and I want to do two transformations: (i) row to column and (ii) concatenate columns. This is my DF:

CAR <- c('BMW','BMW','BMW','FERRARI','FERRARI','VW')
DATE <- c('OCT','NOV','DEC','OCT','DEC','DEC')
TIME <- c(10,12,15,7,11,14)
QUANTITY <- c(115,101,95,88,130,101)
DF <- data.frame(CAR,DATA,TIME,QUANTITY)

I want to transform into this DF2:

CAR <- c('BMW','FERRARI','VW')
OCT <- c('10 N=(115)','7 N=(88)',' N=()')
NOV <- c('12 N=(101)',' N=()',' N=()')
DEC <- c('15 N=(95)','11 N=(130)','14 N=(101)')
DF2 <- data.frame(CAR,OCT,NOV,DEC)

See that the contents of the DATA column turned into 3 columns. Also, I concatenated TIME and QUANTITY, but included the letter “N” and the parentheses. Is this kind of transformation possible?

Body:
We may use sprintf/glue to format the columns and then reshape with pivot_wider

library(dplyr)
library(tidyr)
DF %>%
    mutate(TIMEQ = sprintf('%d N=(%d)', TIME, QUANTITY), .keep = 'unused') %>%
    pivot_wider(names_from = DATE, values_from = TIMEQ)

By default, if the combination is missing, it returns NA, but if we want to fill with a custom value, use values_fill

DF %>%
    mutate(TIMEQ = sprintf('%d N=(%d)', TIME, QUANTITY), .keep = 'unused') %>%
    pivot_wider(names_from = DATE, values_from = TIMEQ, values_fill = "N=())

-output

# A tibble: 3 × 4
  CAR     OCT        NOV        DEC
  <chr>   <chr>      <chr>      <chr>
1 BMW     10 N=(115) 12 N=(101) 15 N=(95)
2 FERRARI 7 N=(88)   N=()       11 N=(130)
3 VW      N=()       N=()       14 N=(101)


问:
The iOS Simulator deployment targets is set to 7.0, but the range of supported deployment target version for this platform is 8.0 to 12.1
I'm getting this below warning message in my Xcode 10.1.

The iOS Simulator deployment targets are set to 7.0, but the range of supported deployment target versions for this platform is 8.0 to 12.1.

My simulator os in 12.1
Xcode 10.1

And I updated my pod file.

My deployment target is 9.0

In my target

答:
This is a known issue on M1 MacBooks. Run flutter upgrade and that should fix it.

Currently working on
M1 Mackbook 12.0.0
Flutter 2.10.0
Dart 2.16.0


问:
Tutorial teaching Ruby syntax/knowledge required to easily learn rails
I am trying to learn ROR these days and have basic knowledge of ruby, but often working with rails, I get to the point where it seems as if I don't know a bit about ruby.

Just to explain the point, in rails we use has_many keyword. I did not learn any such thing when I was going through ruby tutorials but just came to know that it has something to do with meta-programming in ruby (I have no idea what is meta programming).

So I would like to know if there is any book/tutorial which explain all the points/syntax/concepts of ruby, which a newbie would see while programming in rails.

Thanks to "Jonas Elfström", in simple words, what I am looking for is to know "how Rails uses Ruby"

Thanks.

答:
has_many isn't a keyword, it's simply a class method in the ActiveRecord::Associations module.

It's documented here and you can even view the source if you scroll down a bit.

Associations are a set of macro-like class methods for tying objects
  together through foreign keys. They express relationships like
  “Project has one Project Manager” or “Project belongs to a Portfolio”.
  Each macro adds a number of methods to the class which are specialized
  according to the collection or association symbol and the options
  hash. It works much the same way as Ruby’s own attr* methods.

If you already know Ruby the Rails Guides could get you going but it might be easier to learn from one of the books listed at the documentation page or by watching a couple of screencasts.

For books about Ruby I've never seen such praise as what Eloquent Ruby gets.

ContentLicense: CC BY-SA 3.0


问:
Import external user to firebase
I want to import users from an external database to firebase.

The password were hashed with a sha256 function with the password prepended by a salt (which is a UUID).

For example:

```<code>password = "123qwerty!"
salt = "cb60eb29-95a2-418e-be2a-c1c107fb1add"
hash = sha256(salt+password)
# 54ccb21d42c6961aa1b666b7cb0485f85aab2f2323399fb2959ea5e4e9f6f595
</code>```

Now to import this to firebase I would do the following:

users = []*auth.UserToImport
users = append(users, (&auth.UserToImport{}).
    UID("some-uid").
    Email("jon.foo@example.com").
    PasswordHash([]byte("54ccb21d42c6961aa1b666b7cb0485f85aab2f2323399fb2959ea5e4e9f6f595")).
    PasswordSalt([]byte("cb60eb29-95a2-418e-be2a-c1c107fb1add")).
    DisplayName("Jon FOO"))

h := hash.SHA256{
    Rounds:     1,
    InputOrder: hash.InputOrderSaltFirst,
}
res, err := cl.ImportUsers(ctx, users, auth.WithHash(h))
if err != nil {
    log.Fatal(err)
}

```

The user is well imported in firebase (I can see it in the console), but when I try to login, I have this error The password is invalid or the user does not have a password.

I cannot see what is wrong with my way, maybe the Rounds parameter should be updated, but to what value?

Thanks!

答:
I finally found my issue.
In my case I was giving as the PasswordHash the hex representation of the password:

PasswordHash([]byte("54ccb21d42c6961aa1b666b7cb0485f85aab2f2323399fb2959ea5e4e9f6f595")).
```
<p>It turns out I have to decode first the password, like the following:</p>
<pre class="lang-golang prettyprint-override"><code>decoded, err := hex.DecodeString("54ccb21d42c6961aa1b666b7cb0485f85aab2f2323399fb2959ea5e4e9f6f595")
if err != nil {
    return err
}
user := (&auth.UserToImport{}).
    PasswordHash(decoded).
    PasswordSalt([]byte("cb60eb29-95a2-418e-be2a-c1c107fb1add")). // the salt stays the same
    ...

// call ImportUsers with the same hash configuration (Rounds: 1, InputOrder: SaltFirst)
</code>```

After updating this I ran the code and I could now authenticate with my imported user.

Quick note: as mentionned in the comment, the node SDK does not have the option to specify the input order (salt or password first), this seems to be an important missing feature.

Title: Import external user to firebase

Body:
I want to import users from an external database to firebase.

The password were hashed with a sha256 function with the password prepended by a salt (which is a UUID).

For example:

password = "123qwerty!"
salt = "cb60eb29-95a2-418e-be2a-c1c107fb1add"
hash = sha256(salt+password)
# 54ccb21d42c6961aa1b666b7cb0485f85aab2f2323399fb2959ea5e4e9f6f595

Now to import this to firebase I would do the following:

users = []*auth.UserToImport
users = append(users, (&auth.UserToImport{}).
    UID("some-uid").
    Email("jon.foo@example.com").
    PasswordHash([]byte("54ccb21d42c6961aa1b666b7cb0485f85aab2f2323399fb2959ea5e4e9f6f595")).
    PasswordSalt([]byte("cb60eb29-95a2-418e-be2a-c1c107fb1add")).
    DisplayName("Jon FOO"))

h := hash.SHA256{
    Rounds:     1,
    InputOrder: hash.InputOrderSaltFirst,
}
res, err := cl.ImportUsers(ctx, users, auth.WithHash(h))
if err != nil {
    log.Fatal(err)
}

The user is well imported in firebase (I can see it in the console), but when I try to login, I have this error The password is invalid or the user does not have a password.

I cannot see what is wrong with my way, maybe the Rounds parameter should be updated, but to what value?

Thanks!

Body:
I finally found my issue.
In my case I was giving as the PasswordHash the hex representation of the password:

PasswordHash([]byte("54ccb21d42c6961aa1b666b7cb0485f85aab2f2323399fb2959ea5e4e9f6f595")).

It turns out I have to decode first the password, like the following:

decoded, err := hex.DecodeString("54ccb21d42c6961aa1b666b7cb0485f85aab2f2323399fb2959ea5e4e9f6f595")
if err != nil {
    return err
}
user := (&auth.UserToImport{}).
    PasswordHash(decoded).
    PasswordSalt([]byte("cb60eb29-95a2-418e-be2a-c1c107fb1add")). // the salt stays the same
    ...

// call ImportUsers with the same hash configuration (Rounds: 1, InputOrder: SaltFirst)

After updating this I ran the code and I could now authenticate with my imported user.

Quick note: as mentionned in the comment, the node SDK does not have the option to specify the input order (salt or password first), this seems to be an important missing feature.


问:
Using bash script to remove from sentence words longer than [x] characters
I have a sentence (array) and I would like to remove from it all words longer than 8 characters.

Example sentence:

var="one two three four giberish-giberish five giberish-giberish six"
```
<p>I would like to get:</p>
<pre class="lang-bash prettyprint-override"><code>var="one two three four five six"
</code>```

So far I'm using this:

echo $var | tr ' ' '\n' | awk 'length($1) <= 6 { print $1 }' | tr '\n ' ' ' ```
Solution above works fine but as you can see I'm replacing space with newline then filtering words and then replacing back newline with space.

I'm pretty sure there must be better and more "elegant" solution without swapping space/newline.
</code>```

答:
Here is one way to do it:

arr=(one two three four giberish-giberish five giberish-giberish six)
for var in "${arr[@]}"; do (( ${#var} > 8 )) || echo -n "$var "; done
echo # for that newline in the end
```
<p>And another:</p>
<pre class="lang-sh prettyprint-override"><code>awk '{ for(i=1;i<=NF;i++) { if(length($i) < 8) printf "%s ", $i } print "" # for that newline in the end }'
</code>```

And a third!

awk -v RS='[[:space:]]+' 'length < 8 { v=v" "$0 }; END{print substr(v, 2)}'
```

The last one prints a "perfect" single-space delimited string with no extra leading or trailing whitespace.

Body:
I have a sentence (array) and I would like to remove from it all words longer than 8 characters.

Example sentence:

var="one two three four giberish-giberish five giberish-giberish six"

I would like to get:

var="one two three four five six"

So far I'm using this:

echo $var | tr ' ' '\n' | awk 'length($1) <= 6 { print $1 }' | tr '\n ' ' ' ```
Solution above works fine but as you can see I'm replacing space with newline then filtering words and then replacing back newline with space.

I'm pretty sure there must be better and more "elegant" solution without swapping space/newline.

Body:
Here is one way to do it:

arr=(one two three four giberish-giberish five giberish-giberish six)
for var in "${arr[@]}"; do (( ${#var} > 8 )) || echo -n "$var "; done
echo # for that newline in the end

And another:

awk '{ for(i=1;i<=NF;i++) { if(length($i) < 8) printf "%s ", $i } print "" # for that newline in the end }'

And a third!

awk -v RS='[[:space:]]+' 'length < 8 { v=v" "$0 }; END{print substr(v, 2)}'

The last one prints a "perfect" single-space delimited string with no extra leading or trailing whitespace.


问:
How to view the memory size and layout of a specific managed C# reference type?
I would like some tool or method of viewing the size and layout in memory of a specific C# managed reference type, including all of its instance fields. Obviously this is an implementation detail and my program itself doesn't need to know it, but I, the human programmer, would like to understand how the CLR organizes the actual memory layouts of certain of my C# classes for the purposes of optimization and curiosity. (I've read articles and understand the high-level theory about the memory layout of C# objects, but I would like to see the how the CLR actually does it in-practice.)

If it matters, I'm using .NET 6.

答: There's the SOS Debugging Extension which has a DumpClass command. This dumps out information about the EEClass structure for a type, which includes e.g. what offset each field is located at.


问:
dagger.hilt.android.internal.managers.ViewComponentManager$FragmentContextWrapper cannot be cast to android.app.Activity
I'm using a third-party library that has some custom view implementations. In the implementation, they call Utils.showSoftKeyboard(context as Activity). This, along with using the fragment as an @AndroidEntryPoint causes the following exception:

java.lang.ClassCastException: dagger.hilt.android.internal.managers.ViewComponentManager$FragmentContextWrapper cannot be cast to android.app.Activity.

Is there any way to fix this without altering the third-party library?

答:
It might be late for your problem but here's a solution which might help others having the same problem.
You basically should check the context type before trying to cast it.

```<code>  val mContext = if (context is ViewComponentManager.FragmentContextWrapper)
            context.baseContext
        else
            context
</code>```

Inspired by this answer.

Body:
It might be late for your problem but here's a solution which might help others having the same problem.
You basically should check the context type before trying to cast it.

  val mContext = if (context is ViewComponentManager.FragmentContextWrapper)
            context.baseContext
        else
            context

Inspired by this answer.


问:
Multiplying a current day's value by the next day's value
I have a date_column, an X_column and a sales_column.

```<code>01/01/2022 | 3 | 50
02/01/2022 | 4 | 10
03/01/2022 | 1  | 5
</code>```

and I want to multiply:

```<code>50 * 4 = 200
10*1 = 10
...
</code>```

答:
Powerquery ...

If the dates are always consecutive, already sorted by date then most understandable way is :

Add column, index column

Add column, custom column with formula
```<code>= #"Added Index"{[Index]+1}[Column1]
</code>```

Click select the three numerical columns, transform, data type decimal

Add column, custom column with formula
```<code>=[Column2]*[Custom]
</code>```

That will multiply them on each row.  The bottom item will return an error that you could replace with something (right-click column, replace error, and put something else in there in instead)

sample code:

```<code>let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Added Index" = Table.AddIndexColumn(Source, "Index", 0, 1, Int64.Type),
#"Added Custom" = Table.AddColumn(#"Added Index", "Custom", each #"Added Index"{[Index]+1}[Column1]),
#"Changed Type1" = Table.TransformColumnTypes(#"Added Custom",{{"Column2", type number}, {"Index", type number}, {"Custom", type number}}),
#"Added Custom1" = Table.AddColumn(#"Changed Type1", "Custom.1", each [Column2]*[Custom])
in  #"Added Custom1"
</code>```

A more advanced way will do the calculation regardless of the sort order of the data, and will return an error if there is no match for the next day (you could right-click replace error, and put something else in there in instead). Assumes columns in question are called date, Column1 and Column2

add column ... custom column ... with code

```<code>(i)=>Table.SelectRows(Source, each [date]=Date.AddDays(i[date],1))[Column1]{0}
</code>```

then follow steps above for [Column2]*[Custom]

sample full code:

```<code>let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Added Custom" = Table.AddColumn(Source,"Offset",(i)=>Table.SelectRows(Source, each [date]=Date.AddDays(i[date],1))[Column1]{0}),
#"Added Custom1" = Table.AddColumn(#"Added Custom", "Custom", each [Column2]*[Offset])
in  #"Added Custom1"
</code>```

Body:
I have a date_column, an X_column and a sales_column.

01/01/2022 | 3 | 50
02/01/2022 | 4 | 10
03/01/2022 | 1  | 5

and I want to multiply:

50 * 4 = 200
10*1 = 10
...

Body:
Powerquery ...

If the dates are always consecutive, already sorted by date then most understandable way is :

Add column, index column

Add column, custom column with formula

= #"Added Index"{[Index]+1}[Column1]

Click select the three numerical columns, transform, data type decimal

Add column, custom column with formula

=[Column2]*[Custom]

That will multiply them on each row.  The bottom item will return an error that you could replace with something (right-click column, replace error, and put something else in there in instead)

sample code:

let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Added Index" = Table.AddIndexColumn(Source, "Index", 0, 1, Int64.Type),
#"Added Custom" = Table.AddColumn(#"Added Index", "Custom", each #"Added Index"{[Index]+1}[Column1]),
#"Changed Type1" = Table.TransformColumnTypes(#"Added Custom",{{"Column2", type number}, {"Index", type number}, {"Custom", type number}}),
#"Added Custom1" = Table.AddColumn(#"Changed Type1", "Custom.1", each [Column2]*[Custom])
in  #"Added Custom1"

A more advanced way will do the calculation regardless of the sort order of the data, and will return an error if there is no match for the next day (you could right-click replace error, and put something else in there in instead). Assumes columns in question are called date, Column1 and Column2

add column ... custom column ... with code

(i)=>Table.SelectRows(Source, each [date]=Date.AddDays(i[date],1))[Column1]{0}

then follow steps above for [Column2]*[Custom]

sample full code:

let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Added Custom" = Table.AddColumn(Source,"Offset",(i)=>Table.SelectRows(Source, each [date]=Date.AddDays(i[date],1))[Column1]{0}),
#"Added Custom1" = Table.AddColumn(#"Added Custom", "Custom", each [Column2]*[Offset])
in  #"Added Custom1"


问:
Class with virtual function, when derived from QObject, leads to linking error
Following is the code that works fine

class HttpService {
public:
    virtual ~HttpService(); // implemented in .cpp
protected:
    HttpService(struct MHD_Connection *conn) {}
};
class HttpFileService : public HttpService
{
public:
    virtual ~HttpFileService() ; // implemented in .cpp
protected:
    HttpFileService(struct MHD_Connection *conn) : HttpService(conn) {}
};
```

<p>Now, when I make <code>HttpService</code> a derived class of <code>QObject</code>, like below:</p>

<pre class="lang-c prettyprint-override"><code>#include <QObject>                      // change #1
class HttpService  : public QObject {   // change #2
    Q_OBJECT                            // change #3
public:
    virtual ~HttpService();
protected:
    HttpService(struct MHD_Connection *conn) {}
};

class HttpFileService : public HttpService {
    Q_OBJECT                            // change #4
public:
    virtual ~HttpFileService() ;
protected:
    HttpFileService(struct MHD_Connection *conn) : HttpService(conn) {}
};
</code>```

I encounter the following linking error:

```<code>Undefined symbols for architecture x86_64:
  "vtable for HttpService", referenced from:
      HttpService::~HttpService()in httpservice.o
</code>```

Changing HttpService's constructor to the following doesn't help either

```<code>explicit HttpService(QObject *parent = 0) : QObject(parent)
</code>```

答: Are you calling the moc-compiler? If not, remove the Q_OBJECT macros! And do you include / link the results from the moc-compilation?</p>

Body:
Following is the code that works fine

class HttpService {
public:
    virtual ~HttpService(); // implemented in .cpp
protected:
    HttpService(struct MHD_Connection *conn) {}
};
class HttpFileService : public HttpService
{
public:
    virtual ~HttpFileService() ; // implemented in .cpp
protected:
    HttpFileService(struct MHD_Connection *conn) : HttpService(conn) {}
};

Now, when I make HttpService a derived class of QObject, like below:

#include <QObject>                      // change #1
class HttpService  : public QObject {   // change #2
    Q_OBJECT                            // change #3
public:
    virtual ~HttpService();
protected:
    HttpService(struct MHD_Connection *conn) {}
};

class HttpFileService : public HttpService {
    Q_OBJECT                            // change #4
public:
    virtual ~HttpFileService() ;
protected:
    HttpFileService(struct MHD_Connection *conn) : HttpService(conn) {}
};

I encounter the following linking error:

Undefined symbols for architecture x86_64:
  "vtable for HttpService", referenced from:
      HttpService::~HttpService()in httpservice.o

Changing HttpService's constructor to the following doesn't help either

explicit HttpService(QObject *parent = 0) : QObject(parent)


问:
How to change the color of the Text and a SVG on hover in React?
So I have the following React component which acts as a Navbar in my case. Whenever the user hovers over the navbar item it must change its color to whatever is specified. Currently, the Navbar item consists of 2 items: The Icon(SVG) and a text describing what it is.

So hovering over the component must change the color of both the text and the icon.

Here is the current code:

```<code>import { ReactComponent as DashboardIcon } from "../assets/ico_dashboard.svg";
</code>```

          <DashboardIcon className="navLinkHolder" height={50} />
          Dashboard

```

<p>The CSS:</p>

<pre class="lang-css prettyprint-override"><code>a:hover {
  color: yellow;
}
</code>```

Using this code is working on the Text inside the  which is the Dashboard but the SVG is not changing its color. How do I change the color of the SVG? I tried fill: yellow too but it did not work

答:
you can add to 'path' in the SVG the 'className', so use it in parent CSS hover:

```<code><svg width="24" height="24">
      <path className="myIcon" d="M4,11V13H16L10.5,18.5L11.92,19.92L19.84,12L11.92,4.08L10.5,5.5L16,11H4Z"></path>
</svg>
</code>```
```<code>import { ReactComponent as DashboardIcon } from "../assets/ico_dashboard.svg";
</code>```
```<code><div className="navBar">
  <ul className="nav-links">
    <li>
      <div className="divHover">
        <a href="#">
          <DashboardIcon height={50} />
          Dashboard
        </a>
      </div>
    </li>
  </ul>
</div>
</code>```

CSS:

```<code>a:hover .myIcon{
  fill: red;
}
</code>```

or:

```<code>.divHover:hover .myIcon{
   fill: red;
}
</code>```

Body:
So I have the following React component which acts as a Navbar in my case. Whenever the user hovers over the navbar item it must change its color to whatever is specified. Currently, the Navbar item consists of 2 items: The Icon(SVG) and a text describing what it is.

So hovering over the component must change the color of both the text and the icon.

Here is the current code:

import { ReactComponent as DashboardIcon } from "../assets/ico_dashboard.svg";

          <DashboardIcon className="navLinkHolder" height={50} />
          Dashboard

The CSS:

a:hover {
  color: yellow;
}

Using this code is working on the Text inside the  which is the Dashboard but the SVG is not changing its color. How do I change the color of the SVG? I tried fill: yellow too but it did not work

Body:
you can add to 'path' in the SVG the 'className', so use it in parent CSS hover:

<svg width="24" height="24">
      <path className="myIcon" d="M4,11V13H16L10.5,18.5L11.92,19.92L19.84,12L11.92,4.08L10.5,5.5L16,11H4Z"></path>
</svg>

import { ReactComponent as DashboardIcon } from "../assets/ico_dashboard.svg";

<div className="navBar">
  <ul className="nav-links">
    <li>
      <div className="divHover">
        <a href="#">
          <DashboardIcon height={50} />
          Dashboard
        </a>
      </div>
    </li>
  </ul>
</div>

CSS:

a:hover .myIcon{
  fill: red;
}

or:

.divHover:hover .myIcon{
   fill: red;
}


问:
Does loading multiple json files in single test suit is a good practice in cypress?
Does loading multiple json files in single test suit is a good practice in cypress?
Something like this:</p>
```<code>before(() => {
    cy.fixture('productCatalogData').then((datajson) => {
      recipeData = datajson.recipes;
      return recipeData;
    });
    cy.fixture('loginData').then((datajson) => {
      loginData = datajson;
      return loginData;
    });
  });
</code>```

答:
If you need both the json files in one suite, I don't think there should be a problem using fixtures multiple times. However you can shorten the cy.fixture() code a bit like this:

before(() => {
  cy.fixture('productCatalogData').as('productCatalogData')
  cy.fixture('loginData').as('loginData')
})

it('Access fixtures data', function () {
  // The test has to use "function" callback to make sure "this" points at the Mocha context
  //Access fixtures data using this.productCatalogData and this.loginData
})
```

But one thing to add here, cypress removes aliases after every tests. So if you have just one test inside the suite then before() will work fine, but if you have multiple tests you have to use beforeEach().

Body:
Does loading multiple json files in single test suit is a good practice in cypress?
Something like this:

before(() => {
    cy.fixture('productCatalogData').then((datajson) => {
      recipeData = datajson.recipes;
      return recipeData;
    });
    cy.fixture('loginData').then((datajson) => {
      loginData = datajson;
      return loginData;
    });
  });

Body:
If you need both the json files in one suite, I don't think there should be a problem using fixtures multiple times. However you can shorten the cy.fixture() code a bit like this:

before(() => {
  cy.fixture('productCatalogData').as('productCatalogData')
  cy.fixture('loginData').as('loginData')
})

it('Access fixtures data', function () {
  // The test has to use "function" callback to make sure "this" points at the Mocha context
  //Access fixtures data using this.productCatalogData and this.loginData
})

But one thing to add here, cypress removes aliases after every tests. So if you have just one test inside the suite then before() will work fine, but if you have multiple tests you have to use beforeEach().


问:
SwiftUI @Binding Integer value check type error '() -> ()' cannot conform to 'ShapeStyle'
I'm wrapping my head around SwiftUI binding values and I'm stuck trying to check that an Integer doesn't equal 0. When using the following code I get the error type '() -> ()' cannot conform to 'ShapeStyle'. I've also tried wrapping the Int around an object but the same error happened. Can you only use binding for Bools?

```<code>@State private var contentToPresent: Int = 0

var body: some View {
    VStack(spacing: 0) {
        if contentToPresent.wrappedValue != 0 {
            showView(id: $contentToPresent)
        }
    }
}
</code>```

答:
In SwiftUI we don't do any computation in the body method because it slows things down and can break structural identity. Instead, we do it in handlers and then set a state var that the body simply reads from. e.g.

```<code>@State private var present = false
let contentToPresent: Int

// body called when either this View is init again with a different contentToPresent or if present changes.
var body: some View {
    VStack(spacing: 0) {
        if present {
            View2(contentToPresent: contentToPresent)
        }
    }
    .onChange(of: contentToPresent) { newVal
         present = ( newVal != 0 )
    }
}
</code>```

In child Views we use let properties when we only need read access and body will run every time the value changes. If you need write access you can change contentToPresent to be a @Binding var.

Note we usually use NavigationLink or sheet(item:) to present things.

Body:
I'm wrapping my head around SwiftUI binding values and I'm stuck trying to check that an Integer doesn't equal 0. When using the following code I get the error type '() -> ()' cannot conform to 'ShapeStyle'. I've also tried wrapping the Int around an object but the same error happened. Can you only use binding for Bools?

@State private var contentToPresent: Int = 0

var body: some View {
    VStack(spacing: 0) {
        if contentToPresent.wrappedValue != 0 {
            showView(id: $contentToPresent)
        }
    }
}

Body:
In SwiftUI we don't do any computation in the body method because it slows things down and can break structural identity. Instead, we do it in handlers and then set a state var that the body simply reads from. e.g.

@State private var present = false
let contentToPresent: Int

// body called when either this View is init again with a different contentToPresent or if present changes.
var body: some View {
    VStack(spacing: 0) {
        if present {
            View2(contentToPresent: contentToPresent)
        }
    }
    .onChange(of: contentToPresent) { newVal
         present = ( newVal != 0 )
    }
}

In child Views we use let properties when we only need read access and body will run every time the value changes. If you need write access you can change contentToPresent to be a @Binding var.

Note we usually use NavigationLink or sheet(item:) to present things.


问:
Join multiple SampleProvider instances together with a gap between each in NAudio
I am making a class that takes a character array and generates a DTMF tone sequence using NAudio. The tones get generated, each returned as a WaveProvider. My problem is I need to add a gap between each tone, and nothing I've tried has worked.

This is (currently) how I'm generating the sequence:

```<code>public static MemoryStream CreateStreamFromDtmfSequence(DtmfTone[] dtmfTones, int toneDuration, int pauseDuration, int sampleRate, double amplitude)
    {
        WaveFormat waveFormat = Config.getWaveFormat(sampleRate);
        MemoryStream memoryStream = new MemoryStream();
        //WaveFileWriter waveFileWriter = new WaveFileWriter(new IgnoreDisposeStream(memoryStream), waveFormat);

        // Combine tones / sample providers

        MixingWaveProvider32 mixer = new MixingWaveProvider32();

        int delayValue = 0;
        foreach (DtmfTone tone in dtmfTones)
        {
            OffsetSampleProvider offsetSampleProvider = new OffsetSampleProvider(tone.AsWaveProvider(sampleRate, toneDuration, amplitude, pauseDuration).ToSampleProvider());
            offsetSampleProvider.DelayBy = TimeSpan.FromMilliseconds(toneDuration + delayValue);
            SampleToWaveProvider samples = new SampleToWaveProvider(offsetSampleProvider);

            mixer.AddInputStream(samples);

            delayValue += pauseDuration;
        }

        WaveFileWriter.WriteWavFileToStream(memoryStream, mixer);
        //waveFileWriter.Close();
        return memoryStream;
    }
</code>```

There's silence at the beginning of the final stream, but not between the tones themselves like there's supposed to be, and I cannot for the hell of me figure out why.

Here are a couple screenshots of the generated waveform in Adobe Audition. For reference, each tone is 300ms long and is supposed to have a 300ms pause following.

Anyone see a mistake I made somewhere? Is there something I'm missing?

答:
Turns out the answer was just RTFM. They updated the documentation since I last looked (a while ago), and it's now more thorough. From that, I was able to modify my method to work properly.

Instead of using the mixer, I switched to using ConcatenatingSampleProvider to schedule each ISampleProvider instance to play in order... including the generated silence!

Here's the revised code:

```<code>public static MemoryStream CreateStreamFromDtmfSequence(DtmfTone[] dtmfTones, int toneDuration, int pauseDuration, int sampleRate, double amplitude)
    {
        WaveFormat waveFormat = Config.getWaveFormat(sampleRate);
        MemoryStream memoryStream = new MemoryStream();

        // Join sample providers together (silence between tones)
        List<ISampleProvider> master = new List<ISampleProvider>();

        foreach (DtmfTone tone in dtmfTones)
        {
            // Group sample providers
            List<ISampleProvider> sampleProviders = new List<ISampleProvider>();
            sampleProviders.Add(tone.AsWaveProvider(sampleRate, toneDuration, amplitude).ToSampleProvider());

            // Generate silence track
            var silence = new SilenceProvider(waveFormat).ToSampleProvider().Take(TimeSpan.FromMilliseconds(pauseDuration));
            sampleProviders.Add(silence);

            // Combine everything
            ISampleProvider playlist = new ConcatenatingSampleProvider(sampleProviders.ToArray());
            master.Add(playlist);
        }

        WaveFileWriter.WriteWavFileToStream(memoryStream, new ConcatenatingSampleProvider(master).ToWaveProvider());
        return memoryStream;
    }
</code>```

The new waveform now looks like this:

...as it should.

Body:
I am making a class that takes a character array and generates a DTMF tone sequence using NAudio. The tones get generated, each returned as a WaveProvider. My problem is I need to add a gap between each tone, and nothing I've tried has worked.

This is (currently) how I'm generating the sequence:

public static MemoryStream CreateStreamFromDtmfSequence(DtmfTone[] dtmfTones, int toneDuration, int pauseDuration, int sampleRate, double amplitude)
    {
        WaveFormat waveFormat = Config.getWaveFormat(sampleRate);
        MemoryStream memoryStream = new MemoryStream();
        //WaveFileWriter waveFileWriter = new WaveFileWriter(new IgnoreDisposeStream(memoryStream), waveFormat);

        // Combine tones / sample providers

        MixingWaveProvider32 mixer = new MixingWaveProvider32();

        int delayValue = 0;
        foreach (DtmfTone tone in dtmfTones)
        {
            OffsetSampleProvider offsetSampleProvider = new OffsetSampleProvider(tone.AsWaveProvider(sampleRate, toneDuration, amplitude, pauseDuration).ToSampleProvider());
            offsetSampleProvider.DelayBy = TimeSpan.FromMilliseconds(toneDuration + delayValue);
            SampleToWaveProvider samples = new SampleToWaveProvider(offsetSampleProvider);

            mixer.AddInputStream(samples);

            delayValue += pauseDuration;
        }

        WaveFileWriter.WriteWavFileToStream(memoryStream, mixer);
        //waveFileWriter.Close();
        return memoryStream;
    }

There's silence at the beginning of the final stream, but not between the tones themselves like there's supposed to be, and I cannot for the hell of me figure out why.

Here are a couple screenshots of the generated waveform in Adobe Audition. For reference, each tone is 300ms long and is supposed to have a 300ms pause following.

Anyone see a mistake I made somewhere? Is there something I'm missing?

Body:
Turns out the answer was just RTFM. They updated the documentation since I last looked (a while ago), and it's now more thorough. From that, I was able to modify my method to work properly.

Instead of using the mixer, I switched to using ConcatenatingSampleProvider to schedule each ISampleProvider instance to play in order... including the generated silence!

Here's the revised code:

public static MemoryStream CreateStreamFromDtmfSequence(DtmfTone[] dtmfTones, int toneDuration, int pauseDuration, int sampleRate, double amplitude)
    {
        WaveFormat waveFormat = Config.getWaveFormat(sampleRate);
        MemoryStream memoryStream = new MemoryStream();

        // Join sample providers together (silence between tones)
        List<ISampleProvider> master = new List<ISampleProvider>();

        foreach (DtmfTone tone in dtmfTones)
        {
            // Group sample providers
            List<ISampleProvider> sampleProviders = new List<ISampleProvider>();
            sampleProviders.Add(tone.AsWaveProvider(sampleRate, toneDuration, amplitude).ToSampleProvider());

            // Generate silence track
            var silence = new SilenceProvider(waveFormat).ToSampleProvider().Take(TimeSpan.FromMilliseconds(pauseDuration));
            sampleProviders.Add(silence);

            // Combine everything
            ISampleProvider playlist = new ConcatenatingSampleProvider(sampleProviders.ToArray());
            master.Add(playlist);
        }

        WaveFileWriter.WriteWavFileToStream(memoryStream, new ConcatenatingSampleProvider(master).ToWaveProvider());
        return memoryStream;
    }

The new waveform now looks like this:

...as it should.


问:
Focus on Table row TR for accessiblity
I have a requirement to implement accessibility on table rows. The application should ideally be div based and rows should've been li's, but it is an old application and redesigning is not an option. So am forced to tweak and make it accessible. Could any one of you please help me to get focus on a table row? Is is possible at all?

For e.g: The table below, on tab, should first focus on the first row and then the input inside it. Again tabbing should do the same on the next row.

```<code><table>
<tr>
    <td><input type="textbox" /></td>
    <td>some content</td>
<tr>
<tr>
    <td><input type="textbox" /></td>
    <td>some content</td>
<tr>
<tr>
    <td><input type="textbox" /></td>
    <td>some content</td>
<tr>
</table>
</code>```

Any help is highly appreciated.

答: I would do this (using jQuery) by $('tr').first().find('input').first().focus() , I did not know however Coomie's solution. I am not sure if his solution with html will work in IE. There  are however some issues with focus() and limitation, if you decide to use this solution make sure you have read about jQuery focus()</p>

Title: Focus on Table row TR for accessiblity

Body:
I have a requirement to implement accessibility on table rows. The application should ideally be div based and rows should've been li's, but it is an old application and redesigning is not an option. So am forced to tweak and make it accessible. Could any one of you please help me to get focus on a table row? Is is possible at all?

For e.g: The table below, on tab, should first focus on the first row and then the input inside it. Again tabbing should do the same on the next row.

    <input type="textbox" />
    some content

    <input type="textbox" />
    some content

    <input type="textbox" />
    some content

Any help is highly appreciated.


问:
Horizontal Flatlist: Space between items
I'm trying to get space around my items in a horizontal flatlist, no matter how I try it doesn't seem to work:

```<code>const renderItem = ({item}) => {

return (
  <View style={styles.item}>
    <Image
      source={{uri: content.uri}}
      style={styles.image}
    />
    <View>
      <Text style={styles.contentTitle}>{content.title}</Text>
      <Text style={styles.contentText}>{content.releaseDate}</Text>
    </View>
  </View>
)

}

<View style={styles.container}>
  {header}
  <View style={{width: '100%', justifyContent: 'space-around', backgroundColor: 'green'}}>
     <FlatList
        data={data}
        pagingEnabled={true}
        horizontal={true}
        renderItem={renderItem}
        keyExtractor={item => item.id}
        ref={flatList}
      />
  </View>
</View>

const styles = StyleSheet.create({
  container: {
    width: windowWidth,
    marginTop: 15,
    paddingBottom: 15,
    borderBottomWidth: 1,
    borderBottomColor: Colors.borderBlue,
    backgroundColor: Colors.backgroundGenericTransparent,
  },
  item: {
    width: windowWidth / 3.1,
    backgroundColor: 'red',
  },
  image: {
    width: '100%',
    height: 220,
  },
})
</code>```

result:

As you can see the items are all together on the left even though I have added a space-around property on the container. Not show how I can resolve this.

答:
Not sure what you are trying to achieve.
Is that what you want?

snack here

Just add horizontal padding to your container. and no matter how big your items get you will always have spacing left and right. If the item gets too big you can start to scroll.

Body:
I'm trying to get space around my items in a horizontal flatlist, no matter how I try it doesn't seem to work:

const renderItem = ({item}) => {

return (
  <View style={styles.item}>
    <Image
      source={{uri: content.uri}}
      style={styles.image}
    />
    <View>
      <Text style={styles.contentTitle}>{content.title}</Text>
      <Text style={styles.contentText}>{content.releaseDate}</Text>
    </View>
  </View>
)

}

<View style={styles.container}>
  {header}
  <View style={{width: '100%', justifyContent: 'space-around', backgroundColor: 'green'}}>
     <FlatList
        data={data}
        pagingEnabled={true}
        horizontal={true}
        renderItem={renderItem}
        keyExtractor={item => item.id}
        ref={flatList}
      />
  </View>
</View>

const styles = StyleSheet.create({
  container: {
    width: windowWidth,
    marginTop: 15,
    paddingBottom: 15,
    borderBottomWidth: 1,
    borderBottomColor: Colors.borderBlue,
    backgroundColor: Colors.backgroundGenericTransparent,
  },
  item: {
    width: windowWidth / 3.1,
    backgroundColor: 'red',
  },
  image: {
    width: '100%',
    height: 220,
  },
})

result:

As you can see the items are all together on the left even though I have added a space-around property on the container. Not show how I can resolve this.


问:
How to create JSON nested child parent tree with PHP and MySQL(PDO method)
I am trying to build nested parent child JSON tree using PHP and MySQL.
My aim is to create a JSON tree from my MySQL DB and display a tree in front-end using AngularJS. Creating tree is important.

My DB Structure is :

```
╔═══════╦═══════════════════╦═════════╗
║  id   ║       name        ║parent_id║
╠═══════╬═══════════════════╬═════════╣
║   1   ║       Parent      ║    0    ║
║   2   ║       Child-1     ║    1    ║
║   3   ║       Child-2     ║    1    ║
║   4   ║   Grand Child-1   ║    2    ║
║   5   ║   Grand Child-2   ║    2    ║
║   6   ║   Grand Child-3   ║    3    ║
║   7   ║   Grand Child-4   ║    3    ║
╚═══════╩═══════════════════╩═════════╝
```

I need the tree to look like:

```Parent
    |--Child-1
    |    |--Grand Child-1
    |    |_ Grand Child-2
    |--Child-2
    |    |--Grand Child-3
    |    |_ Grand Child-4```

And i have made something like this :

```<code>function hasChild($id){
    $sql = "SELECT count(*) FROM `myTable` WHERE parent_id=".$id;
    $stmt = $this->db->prepare($sql);
    $stmt->execute($a);
    $row = $stmt->fetchAll(PDO::FETCH_ASSOC);
    return $row[0] > 0 ? true : false;
}//function hasChild($id)

// create an index on id
$index = array();
foreach($rows as $i =>$row)
{
    if (hasChild($i)) {
        $index[$row['id']] = $row;
    }
}

// build the tree
foreach($index as $id => $indexRow)
{
    if ($id === 1) continue;
    $parent = $indexRow['parent_id'];
    $index[$parent]['children'][] = $indexRow;
}
unset($indexRow);

echo json_encode($index);
</code>```

But it's clearly not giving me correct json tree :(

I've looked at nesting json and array solutions and something is just not clicking for me, so I was hoping someone could help me out with this. I'm fine with using another way, as long as i can have the same/similar functionality.

Hopefully I was able to portray the situation well enough, but let me know if you need more data.

Thanks in advance!

答:
I had the same problem since few days so therefore found another way to solve this

POSTMAN RESPONSE EARLIER

```<code>{
"Status": 200,
"Data": {
    "MyAssetsList": [
        {
            "AssetsId": 15,
            "UserCredentialId": 7,
            "NickName": "jals",
            "EquipmentId": "BO_15",
            "EquipmentTypeId": 4,
            "EquipmentTypeValue": "Backhoe",
            "MakeId": 1,
            "OEMName": "JCB",
            "ModelId": 1,
            "ModelName": "EX1235",
            "YearOfPurchase": 2022,
            "OtherOEMName": "rw",
            "OtherModelName": 0,
            "MetricId": 1,
            "Capacity": "1.000 Kg",
            "EquipmentAge": "2 Months",
            "ProcessCompletionPercentage": 100
        },
        {
            "AssetsId": 14,
            "UserCredentialId": 7,
            "NickName": "jal",
            "EquipmentId": "",
            "EquipmentTypeId": 4,
            "EquipmentTypeValue": "Backhoe",
            "MakeId": 1,
            "OEMName": "JCB",
            "ModelId": 1,
            "ModelName": "EX1235",
            "YearOfPurchase": 2022,
            "OtherOEMName": "rw",
            "OtherModelName": 0,
            "MetricId": 1,
            "Capacity": "1.000 Kg",
            "EquipmentAge": "2 Months",
            "ProcessCompletionPercentage": 33.33
        },
        {
            "AssetsId": 13,
            "UserCredentialId": 7,
            "NickName": "rest",
            "EquipmentId": "",
            "EquipmentTypeId": 4,
            "EquipmentTypeValue": "Backhoe",
            "MakeId": 1,
            "OEMName": "JCB",
            "ModelId": 1,
            "ModelName": "EX1235",
            "YearOfPurchase": 2022,
            "OtherOEMName": "rw",
            "OtherModelName": 0,
            "MetricId": 1,
            "Capacity": "1.000 Kg",
            "EquipmentAge": "2 Months",
            "ProcessCompletionPercentage": 33.33
        },
        {
            "AssetsId": 11,
            "UserCredentialId": 7,
            "NickName": "test",
            "EquipmentId": "",
            "EquipmentTypeId": 1,
            "EquipmentTypeValue": "Excavator",
            "MakeId": 1,
            "OEMName": "JCB",
            "ModelId": 1,
            "ModelName": "EX1235",
            "YearOfPurchase": 2022,
            "OtherOEMName": 1,
            "OtherModelName": 1,
            "MetricId": 1,
            "Capacity": "1.000 Kg",
            "EquipmentAge": "2 Months",
            "ProcessCompletionPercentage": 33.33
        },
    ]
},
"Message": {
    "SuccessMessage": "My Asset Found Successfully"
}
</code>```

POSTMAN RESPONSE PRETTY AFTER SOLVING TREE STRUCTURE ISSUE

```<code>{
"Status": 200,
"Data": {
    "MyAssets": {
        "AssetsId: 15": {
            "AssetId": 15,
            "EquipmentType": {
                "EquipmentTypeId": 4,
                "EquipmentTypeValue": "Backhoe",
                "EquipmentMake": {
                    "EquipmentMakeId": 1,
                    "EquipmentMakeValue": "JCB"
                },
                "EquipmentModel": {
                    "EquipmentModelId": 1,
                    "EquipmentModelValue": "EX1235"
                },
                "EquipmentYearOfPurchase": 2022,
                "EquipmentAge": "2 Months",
                "OtherOEMName": "rw",
                "OtherModelName": "rw",
                "MetricType": {
                    "MetricId": 1,
                    "Capacity": "1.000 Kg"
                },
                "ProcessCompletionPercentage": 100
            }
        },
        "AssetsId: 14": {
            "AssetId": 14,
            "EquipmentType": {
                "EquipmentTypeId": 4,
                "EquipmentTypeValue": "Backhoe",
                "EquipmentMake": {
                    "EquipmentMakeId": 1,
                    "EquipmentMakeValue": "JCB"
                },
                "EquipmentModel": {
                    "EquipmentModelId": 1,
                    "EquipmentModelValue": "EX1235"
                },
                "EquipmentYearOfPurchase": 2022,
                "EquipmentAge": "2 Months",
                "OtherOEMName": "rw",
                "OtherModelName": "rw",
                "MetricType": {
                    "MetricId": 1,
                    "Capacity": "1.000 Kg"
                },
                "ProcessCompletionPercentage": 33.33
            }
        },
        "AssetsId: 13": {
            "AssetId": 13,
            "EquipmentType": {
                "EquipmentTypeId": 4,
                "EquipmentTypeValue": "Backhoe",
                "EquipmentMake": {
                    "EquipmentMakeId": 1,
                    "EquipmentMakeValue": "JCB"
                },
                "EquipmentModel": {
                    "EquipmentModelId": 1,
                    "EquipmentModelValue": "EX1235"
                },
                "EquipmentYearOfPurchase": 2022,
                "EquipmentAge": "2 Months",
                "OtherOEMName": "rw",
                "OtherModelName": "rw",
                "MetricType": {
                    "MetricId": 1,
                    "Capacity": "1.000 Kg"
                },
                "ProcessCompletionPercentage": 33.33
            }
        },
        "AssetsId: 11": {
            "AssetId": 11,
            "EquipmentType": {
                "EquipmentTypeId": 1,
                "EquipmentTypeValue": "Excavator",
                "EquipmentMake": {
                    "EquipmentMakeId": 1,
                    "EquipmentMakeValue": "JCB"
                },
                "EquipmentModel": {
                    "EquipmentModelId": 1,
                    "EquipmentModelValue": "EX1235"
                },
                "EquipmentYearOfPurchase": 2022,
                "EquipmentAge": "2 Months",
                "OtherOEMName": 1,
                "OtherModelName": 1,
                "MetricType": {
                    "MetricId": 1,
                    "Capacity": "1.000 Kg"
                },
                "ProcessCompletionPercentage": 33.33
            }
        },

    },
    "AssetImageFileReference": "https://localhost/e9/FileServer/AssetsImage/",
    "AssetDocumentFileReference": "https://localhost/e9/FileServer/AssetsDocument/"
},
"Message": {
    "SuccessMessage": "My Asset Found Successfully"
}
</code>```

PHP CODE TO CREATE TREE STRUCTURE LIKE ABOVE IS

```<code>        $A = array();
        $Data->MyAssetsList = $ResultModel; // ResultModel Has query result of mysql

        foreach($ResultModel as $R)
        {
            $A['MyAssets']["AssetsId: ".$R->AssetsId]['AssetId']= $R->AssetsId;
            $A['MyAssets']["AssetsId: ".$R->AssetsId]['EquipmentType']["EquipmentTypeId"]= $R->EquipmentTypeId;
            $A['MyAssets']["AssetsId: ".$R->AssetsId]['EquipmentType']["EquipmentTypeValue"]= $R->EquipmentTypeValue;
            $A['MyAssets']["AssetsId: ".$R->AssetsId]['EquipmentType']["EquipmentMake"]['EquipmentMakeId']= $R->MakeId;
            $A['MyAssets']["AssetsId: ".$R->AssetsId]['EquipmentType']["EquipmentMake"]['EquipmentMakeValue']= $R->OEMName;
            $A['MyAssets']["AssetsId: ".$R->AssetsId]['EquipmentType']["EquipmentModel"]['EquipmentModelId']= $R->ModelId;
            $A['MyAssets']["AssetsId: ".$R->AssetsId]['EquipmentType']["EquipmentModel"]['EquipmentModelValue']= $R->ModelName;
            $A['MyAssets']["AssetsId: ".$R->AssetsId]['EquipmentType']["EquipmentYearOfPurchase"]= $R->YearOfPurchase;
            $A['MyAssets']["AssetsId: ".$R->AssetsId]['EquipmentType']["EquipmentAge"]= $R->EquipmentAge;
            $A['MyAssets']["AssetsId: ".$R->AssetsId]['EquipmentType']["OtherOEMName"]= $R->OtherOEMName;
            $A['MyAssets']["AssetsId: ".$R->AssetsId]['EquipmentType']["OtherModelName"]= $R->OtherOEMName;
            $A['MyAssets']["AssetsId: ".$R->AssetsId]['EquipmentType']["MetricType"]['MetricId']= $R->MetricId;
            $A['MyAssets']["AssetsId: ".$R->AssetsId]['EquipmentType']["MetricType"]['Capacity']= $R->Capacity;
            $A['MyAssets']["AssetsId: ".$R->AssetsId]['EquipmentType']["ProcessCompletionPercentage"]= $R->ProcessCompletionPercentage;

        }

        $A['AssetImageFileReference'] = base_url(PATH_TO_FILESERVER_ASSETSIMAGE);
        $A['AssetDocumentFileReference'] = base_url(PATH_TO_FILESERVER_ASSETSDOCUMENT);
</code>```

Body:
I am trying to build nested parent child JSON tree using PHP and MySQL.
My aim is to create a JSON tree from my MySQL DB and display a tree in front-end using AngularJS. Creating tree is important.

My DB Structure is :

╔═══════╦═══════════════════╦═════════╗
║  id   ║       name        ║parent_id║
╠═══════╬═══════════════════╬═════════╣
║   1   ║       Parent      ║    0    ║
║   2   ║       Child-1     ║    1    ║
║   3   ║       Child-2     ║    1    ║
║   4   ║   Grand Child-1   ║    2    ║
║   5   ║   Grand Child-2   ║    2    ║
║   6   ║   Grand Child-3   ║    3    ║
║   7   ║   Grand Child-4   ║    3    ║
╚═══════╩═══════════════════╩═════════╝

I need the tree to look like:

Parent
    |--Child-1
    |    |--Grand Child-1
    |    |_ Grand Child-2
    |--Child-2
    |    |--Grand Child-3
    |    |_ Grand Child-4

And i have made something like this :

function hasChild($id){
    $sql = "SELECT count(*) FROM `myTable` WHERE parent_id=".$id;
    $stmt = $this->db->prepare($sql);
    $stmt->execute($a);
    $row = $stmt->fetchAll(PDO::FETCH_ASSOC);
    return $row[0] > 0 ? true : false;
}//function hasChild($id)

// create an index on id
$index = array();
foreach($rows as $i =>$row)
{
    if (hasChild($i)) {
        $index[$row['id']] = $row;
    }
}

// build the tree
foreach($index as $id => $indexRow)
{
    if ($id === 1) continue;
    $parent = $indexRow['parent_id'];
    $index[$parent]['children'][] = $indexRow;
}
unset($indexRow);

echo json_encode($index);

But it's clearly not giving me correct json tree :(

I've looked at nesting json and array solutions and something is just not clicking for me, so I was hoping someone could help me out with this. I'm fine with using another way, as long as i can have the same/similar functionality.

Hopefully I was able to portray the situation well enough, but let me know if you need more data.

Thanks in advance!

Body:
I had the same problem since few days so therefore found another way to solve this

POSTMAN RESPONSE EARLIER

{
"Status": 200,
"Data": {
    "MyAssetsList": [
        {
            "AssetsId": 15,
            "UserCredentialId": 7,
            "NickName": "jals",
            "EquipmentId": "BO_15",
            "EquipmentTypeId": 4,
            "EquipmentTypeValue": "Backhoe",
            "MakeId": 1,
            "OEMName": "JCB",
            "ModelId": 1,
            "ModelName": "EX1235",
            "YearOfPurchase": 2022,
            "OtherOEMName": "rw",
            "OtherModelName": 0,
            "MetricId": 1,
            "Capacity": "1.000 Kg",
            "EquipmentAge": "2 Months",
            "ProcessCompletionPercentage": 100
        },
        {
            "AssetsId": 14,
            "UserCredentialId": 7,
            "NickName": "jal",
            "EquipmentId": "",
            "EquipmentTypeId": 4,
            "EquipmentTypeValue": "Backhoe",
            "MakeId": 1,
            "OEMName": "JCB",
            "ModelId": 1,
            "ModelName": "EX1235",
            "YearOfPurchase": 2022,
            "OtherOEMName": "rw",
            "OtherModelName": 0,
            "MetricId": 1,
            "Capacity": "1.000 Kg",
            "EquipmentAge": "2 Months",
            "ProcessCompletionPercentage": 33.33
        },
        {
            "AssetsId": 13,
            "UserCredentialId": 7,
            "NickName": "rest",
            "EquipmentId": "",
            "EquipmentTypeId": 4,
            "EquipmentTypeValue": "Backhoe",
            "MakeId": 1,
            "OEMName": "JCB",
            "ModelId": 1,
            "ModelName": "EX1235",
            "YearOfPurchase": 2022,
            "OtherOEMName": "rw",
            "OtherModelName": 0,
            "MetricId": 1,
            "Capacity": "1.000 Kg",
            "EquipmentAge": "2 Months",
            "ProcessCompletionPercentage": 33.33
        },
        {
            "AssetsId": 11,
            "UserCredentialId": 7,
            "NickName": "test",
            "EquipmentId": "",
            "EquipmentTypeId": 1,
            "EquipmentTypeValue": "Excavator",
            "MakeId": 1,
            "OEMName": "JCB",
            "ModelId": 1,
            "ModelName": "EX1235",
            "YearOfPurchase": 2022,
            "OtherOEMName": 1,
            "OtherModelName": 1,
            "MetricId": 1,
            "Capacity": "1.000 Kg",
            "EquipmentAge": "2 Months",
            "ProcessCompletionPercentage": 33.33
        },
    ]
},
"Message": {
    "SuccessMessage": "My Asset Found Successfully"
}

POSTMAN RESPONSE PRETTY AFTER SOLVING TREE STRUCTURE ISSUE

{
"Status": 200,
"Data": {
    "MyAssets": {
        "AssetsId: 15": {
            "AssetId": 15,
            "EquipmentType": {
                "EquipmentTypeId": 4,
                "EquipmentTypeValue": "Backhoe",
                "EquipmentMake": {
                    "EquipmentMakeId": 1,
                    "EquipmentMakeValue": "JCB"
                },
                "EquipmentModel": {
                    "EquipmentModelId": 1,
                    "EquipmentModelValue": "EX1235"
                },
                "EquipmentYearOfPurchase": 2022,
                "EquipmentAge": "2 Months",
                "OtherOEMName": "rw",
                "OtherModelName": "rw",
                "MetricType": {
                    "MetricId": 1,
                    "Capacity": "1.000 Kg"
                },
                "ProcessCompletionPercentage": 100
            }
        },
        "AssetsId: 14": {
            "AssetId": 14,
            "EquipmentType": {
                "EquipmentTypeId": 4,
                "EquipmentTypeValue": "Backhoe",
                "EquipmentMake": {
                    "EquipmentMakeId": 1,
                    "EquipmentMakeValue": "JCB"
                },
                "EquipmentModel": {
                    "EquipmentModelId": 1,
                    "EquipmentModelValue": "EX1235"
                },
                "EquipmentYearOfPurchase": 2022,
                "EquipmentAge": "2 Months",
                "OtherOEMName": "rw",
                "OtherModelName": "rw",
                "MetricType": {
                    "MetricId": 1,
                    "Capacity": "1.000 Kg"
                },
                "ProcessCompletionPercentage": 33.33
            }
        },
        "AssetsId: 13": {
            "AssetId": 13,
            "EquipmentType": {
                "EquipmentTypeId": 4,
                "EquipmentTypeValue": "Backhoe",
                "EquipmentMake": {
                    "EquipmentMakeId": 1,
                    "EquipmentMakeValue": "JCB"
                },
                "EquipmentModel": {
                    "EquipmentModelId": 1,
                    "EquipmentModelValue": "EX1235"
                },
                "EquipmentYearOfPurchase": 2022,
                "EquipmentAge": "2 Months",
                "OtherOEMName": "rw",
                "OtherModelName": "rw",
                "MetricType": {
                    "MetricId": 1,
                    "Capacity": "1.000 Kg"
                },
                "ProcessCompletionPercentage": 33.33
            }
        },
        "AssetsId: 11": {
            "AssetId": 11,
            "EquipmentType": {
                "EquipmentTypeId": 1,
                "EquipmentTypeValue": "Excavator",
                "EquipmentMake": {
                    "EquipmentMakeId": 1,
                    "EquipmentMakeValue": "JCB"
                },
                "EquipmentModel": {
                    "EquipmentModelId": 1,
                    "EquipmentModelValue": "EX1235"
                },
                "EquipmentYearOfPurchase": 2022,
                "EquipmentAge": "2 Months",
                "OtherOEMName": 1,
                "OtherModelName": 1,
                "MetricType": {
                    "MetricId": 1,
                    "Capacity": "1.000 Kg"
                },
                "ProcessCompletionPercentage": 33.33
            }
        },

    },
    "AssetImageFileReference": "https://localhost/e9/FileServer/AssetsImage/",
    "AssetDocumentFileReference": "https://localhost/e9/FileServer/AssetsDocument/"
},
"Message": {
    "SuccessMessage": "My Asset Found Successfully"
}

PHP CODE TO CREATE TREE STRUCTURE LIKE ABOVE IS

        $A = array();
        $Data->MyAssetsList = $ResultModel; // ResultModel Has query result of mysql

        foreach($ResultModel as $R)
        {
            $A['MyAssets']["AssetsId: ".$R->AssetsId]['AssetId']= $R->AssetsId;
            $A['MyAssets']["AssetsId: ".$R->AssetsId]['EquipmentType']["EquipmentTypeId"]= $R->EquipmentTypeId;
            $A['MyAssets']["AssetsId: ".$R->AssetsId]['EquipmentType']["EquipmentTypeValue"]= $R->EquipmentTypeValue;
            $A['MyAssets']["AssetsId: ".$R->AssetsId]['EquipmentType']["EquipmentMake"]['EquipmentMakeId']= $R->MakeId;
            $A['MyAssets']["AssetsId: ".$R->AssetsId]['EquipmentType']["EquipmentMake"]['EquipmentMakeValue']= $R->OEMName;
            $A['MyAssets']["AssetsId: ".$R->AssetsId]['EquipmentType']["EquipmentModel"]['EquipmentModelId']= $R->ModelId;
            $A['MyAssets']["AssetsId: ".$R->AssetsId]['EquipmentType']["EquipmentModel"]['EquipmentModelValue']= $R->ModelName;
            $A['MyAssets']["AssetsId: ".$R->AssetsId]['EquipmentType']["EquipmentYearOfPurchase"]= $R->YearOfPurchase;
            $A['MyAssets']["AssetsId: ".$R->AssetsId]['EquipmentType']["EquipmentAge"]= $R->EquipmentAge;
            $A['MyAssets']["AssetsId: ".$R->AssetsId]['EquipmentType']["OtherOEMName"]= $R->OtherOEMName;
            $A['MyAssets']["AssetsId: ".$R->AssetsId]['EquipmentType']["OtherModelName"]= $R->OtherOEMName;
            $A['MyAssets']["AssetsId: ".$R->AssetsId]['EquipmentType']["MetricType"]['MetricId']= $R->MetricId;
            $A['MyAssets']["AssetsId: ".$R->AssetsId]['EquipmentType']["MetricType"]['Capacity']= $R->Capacity;
            $A['MyAssets']["AssetsId: ".$R->AssetsId]['EquipmentType']["ProcessCompletionPercentage"]= $R->ProcessCompletionPercentage;

        }

        $A['AssetImageFileReference'] = base_url(PATH_TO_FILESERVER_ASSETSIMAGE);
        $A['AssetDocumentFileReference'] = base_url(PATH_TO_FILESERVER_ASSETSDOCUMENT);


问:
open cv2 python multiply images
I have this simple code and I'm new at learning open cv2. This was supposed to do the chroma key efect but isn't working. Here's the code

```<code>import cv2

objectImage = cv2.imread("falcon.jpg")
background = cv2.imread("florest.jpg")
mask = cv2.imread("mask.png")

falcon = cv2.multiply(objectImage, mask)

back = cv2.multiply(background, (255 - mask))

result = cv2.add(falcon, back)

cv2.imshow("Image",result)
cv2.waitKey(0)
cv2.destroyWindow("Image")
</code>```

And here's the result:

And here is what it was supposed to look like:

Thanks to anyone in advance!

答:
A better alternative would be

result = cv2.bitwise_and(image, mask)
```
<hr />
<p>For anyone who thinks that they are OK with</p>
<pre class="lang-py prettyprint-override"><code>result = (image/255.)*(mask/255)*255
</code>```

just because it does generate a similar output. Avoid it as it does not involve OpenCV ensuring that the image and the mask are homogeneous (same shape and stride). When feeding the result as inputs to other OpenCV methods like findContours(), you are very likely to enter into high-verbose errors which only tell you that the image properties are not same (even though you think .shape for both image and mask outputs the same values.) Read more on strides difference when the shape seems same.

Also, ensure that both image and mask possess the same datatype (use mask.dtype) before using the together.

Title: open cv2 python multiply images

Body:
I have this simple code and I'm new at learning open cv2. This was supposed to do the chroma key efect but isn't working. Here's the code

import cv2

objectImage = cv2.imread("falcon.jpg")
background = cv2.imread("florest.jpg")
mask = cv2.imread("mask.png")

falcon = cv2.multiply(objectImage, mask)

back = cv2.multiply(background, (255 - mask))

result = cv2.add(falcon, back)

cv2.imshow("Image",result)
cv2.waitKey(0)
cv2.destroyWindow("Image")

And here's the result:

And here is what it was supposed to look like:

Thanks to anyone in advance!

Body:
A better alternative would be

result = cv2.bitwise_and(image, mask)

For anyone who thinks that they are OK with

result = (image/255.)*(mask/255)*255

just because it does generate a similar output. Avoid it as it does not involve OpenCV ensuring that the image and the mask are homogeneous (same shape and stride). When feeding the result as inputs to other OpenCV methods like findContours(), you are very likely to enter into high-verbose errors which only tell you that the image properties are not same (even though you think .shape for both image and mask outputs the same values.) Read more on strides difference when the shape seems same.

Also, ensure that both image and mask possess the same datatype (use mask.dtype) before using the together.


问:
Yarn keeps telling me to rename folder
Yesterday, yarn worked just fine, but today yarn absolutely refuses to work. Running any kind of yarn command fails.

```<code>Internal Error: EPERM: operation not permitted, rename 'C:\Users\NAME\.node\corepack\corepack-4304-ea1e7c84.0eb04' -> 'C:\Users\NAME\.node\corepack\yarn\3.1.1'
</code>```

I tried following the instructions.

I also noticed that the referenced .node folder was read-only. This is weird because every time I try to use yarn, the corepack-RANDOMSTRING is a new folder.

Removing read-only from the folder and checking if it has been removed says it is read only again.

答:
Make sure you are running the CMD prompt as Administrator

Then install Yarn
npm install --global yarn

Verify that Yarn installed correctly
yarn --version
It should print the version number.

If that doesn't work try adding the --force flag as @sfuqua mentions in the comments so npm install --global yarn --force

Note:
Reading through this article https://github.com/yarnpkg/yarn/issues/992 It looks like there are many reasons why this could occur.

Title: Yarn keeps telling me to rename folder

Body:
Yesterday, yarn worked just fine, but today yarn absolutely refuses to work. Running any kind of yarn command fails.

Internal Error: EPERM: operation not permitted, rename 'C:\Users\NAME\.node\corepack\corepack-4304-ea1e7c84.0eb04' -> 'C:\Users\NAME\.node\corepack\yarn\3.1.1'

I tried following the instructions.

I also noticed that the referenced .node folder was read-only. This is weird because every time I try to use yarn, the corepack-RANDOMSTRING is a new folder.

Removing read-only from the folder and checking if it has been removed says it is read only again.


答:
You can use

#!/bin/bash
var="one two three four giberish-giberish five giberish-giberish six"
awk 'BEGIN{RS=ORS=" "} length($0) <= 6' <<< "$var"
# -> one two three four five six
```
<p>See the online demo.</p>
<p>The <code>BEGIN{RS=ORS=" "}</code> sets the record input/output separator to a space and <code>length($0) <= 6</code> only keeps the fields that are equal or shorter than 6 chars.</p>
<p>You can also consider the workarounds with GNU <code>sed</code> and <code>perl</code>:</p>
<pre class="lang-sh prettyprint-override"><code>sed -E 's/\s*\S{7,}//g' <<< "$var"
perl -pe 's/\s*\S{7,}//g' <<< "$var"
</code>```

See this online demo.

A non-GNU sed workaround could look like

sed 's/[[:space:]]*[^[:space:]]\{7,\}//g' <<< "$var"
```

Here, all occurrences of zero or more whitespace (\s*, [[:space:]]*) followed with seven or more non-whitespace chars (\S{7,}, [^[:space:]]\{7,\}) are removed.

Title: Using bash script to remove from sentence words longer than [x] characters

Body:
I have a sentence (array) and I would like to remove from it all words longer than 8 characters.

Example sentence:

var="one two three four giberish-giberish five giberish-giberish six"

I would like to get:

var="one two three four five six"

So far I'm using this:

echo $var | tr ' ' '\n' | awk 'length($1) <= 6 { print $1 }' | tr '\n ' ' ' ```
Solution above works fine but as you can see I'm replacing space with newline then filtering words and then replacing back newline with space.

I'm pretty sure there must be better and more "elegant" solution without swapping space/newline.

Body:
You can use

#!/bin/bash
var="one two three four giberish-giberish five giberish-giberish six"
awk 'BEGIN{RS=ORS=" "} length($0) <= 6' <<< "$var"
# -> one two three four five six

See the online demo.

The BEGIN{RS=ORS=" "} sets the record input/output separator to a space and length($0) <= 6 only keeps the fields that are equal or shorter than 6 chars.

You can also consider the workarounds with GNU sed and perl:

sed -E 's/\s*\S{7,}//g' <<< "$var"
perl -pe 's/\s*\S{7,}//g' <<< "$var"

See this online demo.

A non-GNU sed workaround could look like

sed 's/[[:space:]]*[^[:space:]]\{7,\}//g' <<< "$var"

Here, all occurrences of zero or more whitespace (\s*, [[:space:]]*) followed with seven or more non-whitespace chars (\S{7,}, [^[:space:]]\{7,\}) are removed.


问:
Why can't I get two lists from one list comprehension?
So I have an array of the following form:

```<code>[(1, u'first_type', u'data_gid_1'),
 (2, u'first_type', u'data_gid_2'),
 (3, u'first_type', u'data_gid_3'),
 (4, u'first_type', u'data_gid_4')]
</code>```

Now I want to extract the first and the last element of each inside list into separate lists. So if I do:

```<code>>>> ids = [dat[0] for dat in all_data]
>>> gds = [dat[2] for dat in all_data]
</code>```

This works as I expect it to. However I was trying to merge these two into one call, something like:

```<code> (ids, gds) = [(dat[0], dat[2]) for dat in all_data]
</code>```

This however fails with an:
     ValueError: too many values to unpack

So could anyone explain why this is happening and if what I am trying to do is even possible.

Regards,
Bogdan

答:
Since you are creating two separate lists, try this:

```<code>ids, dgs = [(dat[0]) for dat in all_data], [(dat[2]) for dat in all_data]
</code>```

or you can unpack it to a single list with the command you used:

```<code>x = [(dat[0], dat[2]) for dat in all_data]
</code>```

Body:
So I have an array of the following form:

[(1, u'first_type', u'data_gid_1'),
 (2, u'first_type', u'data_gid_2'),
 (3, u'first_type', u'data_gid_3'),
 (4, u'first_type', u'data_gid_4')]

Now I want to extract the first and the last element of each inside list into separate lists. So if I do:

>>> ids = [dat[0] for dat in all_data]
>>> gds = [dat[2] for dat in all_data]

This works as I expect it to. However I was trying to merge these two into one call, something like:

 (ids, gds) = [(dat[0], dat[2]) for dat in all_data]

This however fails with an:
     ValueError: too many values to unpack

So could anyone explain why this is happening and if what I am trying to do is even possible.

Regards,
Bogdan

Body:
Since you are creating two separate lists, try this:

ids, dgs = [(dat[0]) for dat in all_data], [(dat[2]) for dat in all_data]

or you can unpack it to a single list with the command you used:

x = [(dat[0], dat[2]) for dat in all_data]


问:
Crashlytics and obfuscated Flutter stack traces
Is there a way to send symbols from flutter build appbundle --release --obfuscate --split-debug-info=... to Crashlytics for automatic deobfuscation?

答:
Mapping files to deobfuscate Android stacktraces on Crashlytics can be uploaded automatically by configuring firebaseCrashlytics.mappingFileUploadEnabled to true in your app/build.gradle as mentioned in the documentation.

However, if you're referring to Android NDK crash reports, here's the guide that you can follow to automatically upload symbols.


问:
Twig Setting Select Option on a dropdown
I am currently writing a php mvc  from scratch and using twig as my template engine and need some assistance setting the selected option on a drop down list. Currently in my model I have an sql query that pull all list of supervisors and drops them in my drop down list using the twig for loop but I need to some how select a user’s supervisor if it matches up.

I apologize now as I am new to twig

View:

```<code><select class="form-control" id="supervisor">
      {% for supervisor in supervisor %}
      <option value="{{supervisor.fname}} {{supervisor.lname}}" >{{supervisor.fname}} {{supervisor.lname}}</option>
      {% endfor %}
</select>
</code>```

Tried:

```<code><select class="form-control" id="supervisor">
      {% for supervisor in supervisor %}
{% if {{supervisor.fname}} {{supervisor.lname}} == {{ user.supervisor }} %}
            <option value=”{{supervisor.fname}} {{supervisor.lname}}” selected>{{supervisor.fname}} {{supervisor.lname}}</option>
{% else %}
    <option value=”{{supervisor.fname}} {{supervisor.lname}}”>{{supervisor.fname}} {{supervisor.lname}}</option>
{% endif %}
      {% endfor %}
</select>
</code>```

答:
Assuming you have a form called form and therein a select field called field, You could simply do the following:

```<code>{% do form.field.setRendered %}
<select id="{{ form.field.vars.id }}"
        name="{{ form.field.vars.name }}">
    {% for option in form.field.vars.choices %}
        <option {{ form.field.vars.value == option.value ? 'selected' : '' }}
                value="{{ option.value }}">
            {{ option.label }}
        </option>
    {% endfor %}
</select>
</code>```

Body:
I am currently writing a php mvc  from scratch and using twig as my template engine and need some assistance setting the selected option on a drop down list. Currently in my model I have an sql query that pull all list of supervisors and drops them in my drop down list using the twig for loop but I need to some how select a user’s supervisor if it matches up.

I apologize now as I am new to twig

View:

<select class="form-control" id="supervisor">
      {% for supervisor in supervisor %}
      <option value="{{supervisor.fname}} {{supervisor.lname}}" >{{supervisor.fname}} {{supervisor.lname}}</option>
      {% endfor %}
</select>

Tried:

<select class="form-control" id="supervisor">
      {% for supervisor in supervisor %}
{% if {{supervisor.fname}} {{supervisor.lname}} == {{ user.supervisor }} %}
            <option value=”{{supervisor.fname}} {{supervisor.lname}}” selected>{{supervisor.fname}} {{supervisor.lname}}</option>
{% else %}
    <option value=”{{supervisor.fname}} {{supervisor.lname}}”>{{supervisor.fname}} {{supervisor.lname}}</option>
{% endif %}
      {% endfor %}
</select>

Body:
Assuming you have a form called form and therein a select field called field, You could simply do the following:

{% do form.field.setRendered %}
<select id="{{ form.field.vars.id }}"
        name="{{ form.field.vars.name }}">
    {% for option in form.field.vars.choices %}
        <option {{ form.field.vars.value == option.value ? 'selected' : '' }}
                value="{{ option.value }}">
            {{ option.label }}
        </option>
    {% endfor %}
</select>


问:
Using bash script to remove from sentence words longer than [x] characters
I have a sentence (array) and I would like to remove from it all words longer than 8 characters.

Example sentence:

var="one two three four giberish-giberish five giberish-giberish six"
```
<p>I would like to get:</p>
<pre class="lang-bash prettyprint-override"><code>var="one two three four five six"
</code>```

So far I'm using this:

echo $var | tr ' ' '\n' | awk 'length($1) <= 6 { print $1 }' | tr '\n ' ' ' ```
Solution above works fine but as you can see I'm replacing space with newline then filtering words and then replacing back newline with space.

I'm pretty sure there must be better and more "elegant" solution without swapping space/newline.
</code>```

答:
Using sed

```<code>$ sed 's/\<[a-z-]\{8,\}\> //g' file
var="one two three four five six"
</code>```

Body:
Using sed

$ sed 's/\<[a-z-]\{8,\}\> //g' file
var="one two three four five six"


问:
End play if database does not exits
I have created the following playbook, to check if a database exists:

- name: Check database exits
  shell: |
    mysql -hmysqlhost -uroot -ppassword -e "show databases" | egrep db"
  register: mysql_exist

- name: Show database
  debug:
    msg: "{{ mysql_exist.stdout }}"
```
<p>My idea is to finish the playbook if the database does not exist and show a message, I tried this but it does not work, otherwise I should continue to the next task.</p>
<pre class="lang-yaml prettyprint-override"><code>- name: Check database exits
  shell: |
    mysql -hmysqlhost -uroot -ppassword -e "show databases" | egrep db"
  register: mysql_exist

- name: End Playbook If database not exits.
   meta: end_play
   when: mysql_exist == 0

- name: Show database
  debug:
    msg: "{{ mysql_exist.stdout }}"

## other tasks
</code>```

How can I create a playbook to check if a database exists and if it does not exist, it must display the message The database does not exist and finish the playbook without running other tasks?

答:
if you want to show a message if playbook has to finish, use a block:

(you dont show the output of your register when a db doesnt exist so, i suppose your test in when condition is ok!!)

```<code>- block:
    - name: "end play "
      debug:
        msg: "db doesnt exist"

    - meta: end_play
  when: mysql_exist == 0
</code>```

so the playbook is finished after the message displaying

Title: End play if database does not exits

Body:
I have created the following playbook, to check if a database exists:

- name: Check database exits
  shell: |
    mysql -hmysqlhost -uroot -ppassword -e "show databases" | egrep db"
  register: mysql_exist

- name: Show database
  debug:
    msg: "{{ mysql_exist.stdout }}"

My idea is to finish the playbook if the database does not exist and show a message, I tried this but it does not work, otherwise I should continue to the next task.

- name: Check database exits
  shell: |
    mysql -hmysqlhost -uroot -ppassword -e "show databases" | egrep db"
  register: mysql_exist

- name: End Playbook If database not exits.
   meta: end_play
   when: mysql_exist == 0

- name: Show database
  debug:
    msg: "{{ mysql_exist.stdout }}"

## other tasks

How can I create a playbook to check if a database exists and if it does not exist, it must display the message The database does not exist and finish the playbook without running other tasks?

Body:
if you want to show a message if playbook has to finish, use a block:

(you dont show the output of your register when a db doesnt exist so, i suppose your test in when condition is ok!!)

- block:
    - name: "end play "
      debug:
        msg: "db doesnt exist"

    - meta: end_play
  when: mysql_exist == 0

so the playbook is finished after the message displaying


问:
Google 400 Error: invalid request Custom scheme URIs are not allowed for 'Web' client type
When I am signing into Gmail in my iOS App, I am getting the below error (screenshot) and the sign-in fields do not appear. We are loading the sign-in screen in a WKWebView.

We are using a custom URI redirect but why is google throwing this error now. What are the alternatives to a custom URI?

Swift 2.3 project

Using OAuthSwift v0.6.0 cocoapod

This started quite recently only in the past week or so I believe something changed with Google's APIs.

I have read that google is deprecating webviews for OAuth and will block requests on April 20, 2017. As seen here in a Google Developers Blog:
https://developers.googleblog.com/2016/08/modernizing-oauth-interactions-in-native-apps.html

Does this mean I already need to use  or is there another viable solution? I thought I had more time before needing to update this.

答:
I was using Meteor with Cordova and Meteor's official google integration, which relies on cordova-plugin-googleplus.

I had to:

create both an iOS and a web Client ID

use the web Client ID on the settings / server / database as documented

but then use the reverse of the iOS web client as the REVERSED_CLIENT_ID for cordova-plugin-googleplus


问:
Returning many-to-one composite in SQL in one row
I have the following tables

```<code>User
---------------------------
UserID, FirstName, LastName

Role
---------------------------
RoleID, UserID, RoleName
</code>```

Assuming a many to one relationship between Role and User what is the best way I can return in one query a user along with all the roles they might be in, in a single row?

Previously I have always loaded the Roles (or similar data) in a separate query but the problem is that if your data grows this technique becomes too slow.

答:
This should give you a single row per user in the following format

```<code>WITH cte (userId, roleList, roleNameTemp, level)
as
(
    SELECT  userId
            , CAST( '' AS VARCHAR(max) )
            , CAST( '' AS VARCHAR(200) )
            , 0 level
    FROM    Role
    GROUP BY UserId
    UNION ALL
    SELECT  r.userId
            , roleList +
                CASE WHEN level = 0 THEN '' ELSE ', ' END + RoleName
            , CAST( RoleName AS VARCHAR(200))
            , level + 1
    FROM CTE c
    INNER JOIN Role r ON c.userId = r.userid
    WHERE   r.RoleName  > c.roleNameTemp
)

SELECT      UserId
            ,FirstName
            ,LastName
            ,roleList
FROM
(
    SELECT      u.UserId
                ,u.FirstName
                ,u.LastName
                ,c.roleList
                ,ROW_NUMBER() OVER (Partition by c.userid order by level desc) rowNumber
    FROM        cte c
    INNER JOIN  [User] u on c.userId = u.UserId
)   r
WHERE rownumber = 1
</code>```

Body:
I have the following tables

User
---------------------------
UserID, FirstName, LastName

Role
---------------------------
RoleID, UserID, RoleName

Assuming a many to one relationship between Role and User what is the best way I can return in one query a user along with all the roles they might be in, in a single row?

Previously I have always loaded the Roles (or similar data) in a separate query but the problem is that if your data grows this technique becomes too slow.

Body:
This should give you a single row per user in the following format

WITH cte (userId, roleList, roleNameTemp, level)
as
(
    SELECT  userId
            , CAST( '' AS VARCHAR(max) )
            , CAST( '' AS VARCHAR(200) )
            , 0 level
    FROM    Role
    GROUP BY UserId
    UNION ALL
    SELECT  r.userId
            , roleList +
                CASE WHEN level = 0 THEN '' ELSE ', ' END + RoleName
            , CAST( RoleName AS VARCHAR(200))
            , level + 1
    FROM CTE c
    INNER JOIN Role r ON c.userId = r.userid
    WHERE   r.RoleName  > c.roleNameTemp
)

SELECT      UserId
            ,FirstName
            ,LastName
            ,roleList
FROM
(
    SELECT      u.UserId
                ,u.FirstName
                ,u.LastName
                ,c.roleList
                ,ROW_NUMBER() OVER (Partition by c.userid order by level desc) rowNumber
    FROM        cte c
    INNER JOIN  [User] u on c.userId = u.UserId
)   r
WHERE rownumber = 1