问:
How do I update the column in postgresql python?
I am trying to add a new column in existing table and want to populate that column in database, there is a predictions column which is dataframe it is giving me error what I am doing wrong,

Code:

```<code>conn = create_connection()
cur = conn.cursor()

query = "ALTER TABLE STOCK_MARKET_FORECASTING ADD COLUMN predictions float"
cur.execute(query)

# Inserting predictions in database
def inserting_records(df):
    for i in range(0 ,len(df)):
        values = (df['Predicted_values_Hourly_Interval'][i])
        cur.execute("UPDATE STOCK_MARKET_FORECASTING SET (predictions) VALUES (%s)", values)
    conn.commit()
    print("Records created successfully")
inserting_records(predictions)
</code>```

答:
You're passing in a single value – cur.execute requires a tuple of values.

You're probably looking for INSERT, not UPDATE. UPDATE updates existing rows.

```<code>def inserting_records(df):
    series = df['Predicted_values_Hourly_Interval']
    for val in series:
        cur.execute("INSERT INTO STOCK_MARKET_FORECASTING (predictions) VALUES (%s)", (val, ))
    conn.commit()
</code>```

might be what you're looking for.

Body:
I am trying to add a new column in existing table and want to populate that column in database, there is a predictions column which is dataframe it is giving me error what I am doing wrong,

Code:

conn = create_connection()
cur = conn.cursor()

query = "ALTER TABLE STOCK_MARKET_FORECASTING ADD COLUMN predictions float"
cur.execute(query)

# Inserting predictions in database
def inserting_records(df):
    for i in range(0 ,len(df)):
        values = (df['Predicted_values_Hourly_Interval'][i])
        cur.execute("UPDATE STOCK_MARKET_FORECASTING SET (predictions) VALUES (%s)", values)
    conn.commit()
    print("Records created successfully")
inserting_records(predictions)

Body:
You're passing in a single value – cur.execute requires a tuple of values.

You're probably looking for INSERT, not UPDATE. UPDATE updates existing rows.

def inserting_records(df):
    series = df['Predicted_values_Hourly_Interval']
    for val in series:
        cur.execute("INSERT INTO STOCK_MARKET_FORECASTING (predictions) VALUES (%s)", (val, ))
    conn.commit()

might be what you're looking for.


来源: stackexchange

问:
Docker nginx php-fpm not serving php
I'm trying to setup nginx and php-fpm images to work together for a Laravel application. This is my set up:

docker-compose.yml

```<code>version: "3.8"

services:
    server:
        container_name: nginx
        build:
            context: .
            dockerfile: docker/nginx/Dockerfile
        volumes:
            - ./src/public:/var/www/html/public
        ports:
            - "8888:80"
        depends_on:
            - php
        networks:
            - laravel_net
    php:
        container_name: php
        build:
            context: .
            dockerfile: docker/php/Dockerfile
        ports:
            - "9000:9000"
        volumes:
            - ./src:/var/www/html
        networks:
            - laravel_net
networks:
    laravel_net:
        driver: 'bridge'
</code>```

Nginx

```<code>FROM nginx:stable-alpine

# puts app.conf into the container as /etc/nginx/nginx.conf
# has by default this: include /etc/nginx/conf.d/*.conf;
COPY docker/nginx/conf.d/*.conf /etc/nginx/conf.d/

WORKDIR /var/www/html
COPY ./src/public /var/www/html/public
</code>```

docker/nginx/conf.d/app.conf

```<code>server {
    listen 80;
    server_name laravel.local;
    index index.php index.html;
    error_log /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;
    root /var/www/html/public;

    location / {
        try_files $uri /index.php$is_args$args;
    }

    location ~ \.php {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param SCRIPT_NAME $fastcgi_script_name;
        fastcgi_index index.php;
        fastcgi_pass php:9000;
    }
}
</code>```

PHP

```<code>FROM php:8.1-fpm-alpine

WORKDIR /var/www/html
COPY ./src /var/www/html

EXPOSE 9000
</code>```

Inside src folder is where the laravel app should live so for now I'm just outputting phpinfo() on the public dir just to check that everything is working as expected
src/public/index.php

```<code><?php

phpinfo();

</code>```

If I run docker-compose up --build and docker ps I can see the containers running

```<code>% docker ps
CONTAINER ID   IMAGE                 COMMAND                  CREATED         STATUS         PORTS                    NAMES
abc123   laravel_server   "/docker-entrypoint.…"   8 seconds ago   Up 6 seconds   0.0.0.0:8888->80/tcp     nginx
abc456   laravel_php      "docker-php-entrypoi…"   8 seconds ago   Up 7 seconds   0.0.0.0:9000->9000/tcp   php
</code>```

also on both docker-compose exec server /bin/sh and docker-compose exec php /bin/shI can see the index.php file inside the container

```<code>docker-compose exec server sh
/var/www/html # cat public/index.php
<?php

phpinfo();
/var/www/html # ls -la public
total 12
drwxr-xr-x    2 root     root          4096 Feb 12 13:41 .
drwxr-xr-x    1 root     root          4096 Feb 12 13:41 ..
-rw-r--r--    1 root     root            18 Feb 12 12:51 index.php

docker-compose exec php sh
/var/www/html # ls -lah public/
total 4K
drwxr-xr-x    3 root     root          96 Feb 12 13:42 .
drwxr-xr-x    3 root     root          96 Feb 10 21:28 ..
-rw-r--r--    1 root     root          18 Feb 12 13:42 index.php
/var/www/html # cat public/index.php
<?php

phpinfo();
</code>```

However when I try to access http://localhost:8888 from the browser I get the default Welcome to nginx! page. Any ideas what I'm doing wrong?

答:
I think the problem is nginx config. You are copying app.conf to /etc/nginx/conf.d/ but there already exists default config /etc/nginx/conf.d/default.conf. Because you are seeing the default nginx page I would assume the default one is used.

Try to rename app.conf to default.conf or change copy command to

```<code>COPY docker/nginx/conf.d/app.conf /etc/nginx/conf.d/default.conf
</code>```

ContentLicense: CC BY-SA 4.0

Title: Docker nginx php-fpm not serving php

Body:
I'm trying to setup nginx and php-fpm images to work together for a Laravel application. This is my set up:

docker-compose.yml

version: "3.8"

services:
    server:
        container_name: nginx
        build:
            context: .
            dockerfile: docker/nginx/Dockerfile
        volumes:
            - ./src/public:/var/www/html/public
        ports:
            - "8888:80"
        depends_on:
            - php
        networks:
            - laravel_net
    php:
        container_name: php
        build:
            context: .
            dockerfile: docker/php/Dockerfile
        ports:
            - "9000:9000"
        volumes:
            - ./src:/var/www/html
        networks:
            - laravel_net
networks:
    laravel_net:
        driver: 'bridge'

Nginx

FROM nginx:stable-alpine

# puts app.conf into the container as /etc/nginx/nginx.conf
# has by default this: include /etc/nginx/conf.d/*.conf;
COPY docker/nginx/conf.d/*.conf /etc/nginx/conf.d/

WORKDIR /var/www/html
COPY ./src/public /var/www/html/public

docker/nginx/conf.d/app.conf

server {
    listen 80;
    server_name laravel.local;
    index index.php index.html;
    error_log /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;
    root /var/www/html/public;

    location / {
        try_files $uri /index.php$is_args$args;
    }

    location ~ \.php {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param SCRIPT_NAME $fastcgi_script_name;
        fastcgi_index index.php;
        fastcgi_pass php:9000;
    }
}

PHP

FROM php:8.1-fpm-alpine

WORKDIR /var/www/html
COPY ./src /var/www/html

EXPOSE 9000

Inside src folder is where the laravel app should live so for now I'm just outputting phpinfo() on the public dir just to check that everything is working as expected
src/public/index.php

<?php

phpinfo();

If I run docker-compose up --build and docker ps I can see the containers running

% docker ps
CONTAINER ID   IMAGE                 COMMAND                  CREATED         STATUS         PORTS                    NAMES
abc123   laravel_server   "/docker-entrypoint.…"   8 seconds ago   Up 6 seconds   0.0.0.0:8888->80/tcp     nginx
abc456   laravel_php      "docker-php-entrypoi…"   8 seconds ago   Up 7 seconds   0.0.0.0:9000->9000/tcp   php

also on both docker-compose exec server /bin/sh and docker-compose exec php /bin/shI can see the index.php file inside the container

docker-compose exec server sh
/var/www/html # cat public/index.php
<?php

phpinfo();
/var/www/html # ls -la public
total 12
drwxr-xr-x    2 root     root          4096 Feb 12 13:41 .
drwxr-xr-x    1 root     root          4096 Feb 12 13:41 ..
-rw-r--r--    1 root     root            18 Feb 12 12:51 index.php

docker-compose exec php sh
/var/www/html # ls -lah public/
total 4K
drwxr-xr-x    3 root     root          96 Feb 12 13:42 .
drwxr-xr-x    3 root     root          96 Feb 10 21:28 ..
-rw-r--r--    1 root     root          18 Feb 12 13:42 index.php
/var/www/html # cat public/index.php
<?php

phpinfo();

However when I try to access http://localhost:8888 from the browser I get the default Welcome to nginx! page. Any ideas what I'm doing wrong?

Body:
I think the problem is nginx config. You are copying app.conf to /etc/nginx/conf.d/ but there already exists default config /etc/nginx/conf.d/default.conf. Because you are seeing the default nginx page I would assume the default one is used.

Try to rename app.conf to default.conf or change copy command to

COPY docker/nginx/conf.d/app.conf /etc/nginx/conf.d/default.conf


问:
Contract Violation; expected: real?; given #f
I'm sorry if this question has been answered before, but I've looked around and I can't really understand the explanation as to why I'm getting this error.

From what I understand I'm asking if a statement is true and then if it is I'm asking it to return an expression. And apparently I'm not allowed to get #t/#f answers and expressions? I'm not sure. Could someone help me understand.

This is my code.

```<code>(define (piecewise x)
  (define pi 3.142)
  (cond
    ((> x (* pi 2)) (- x (* 2 pi)))
    ((or ( > x (* pi -1) (= x ( * -1 pi)))) (sin x))
    ((or ( < x (* 2 pi)) (= x (* 2 pi))) (sin x))
    (else (- (- 1 x) pi))))
</code>```

答:
If I may, if we take all of the suggestions and use them to simplify the code a bit, we might get the following:

```<code>(define (piecewise x)
  (let* ((pi 3.142)
         (tau (* 2 pi)))
    (cond
     ((> x tau)
      (- x tau))
     ((or (>= x (- pi))
          (<= x tau))
      (sin x))
     (else (+ x pi)))))
</code>```

This runs without errors under both Racket and Guile. Whether it computes the function correctly, only the OP can say for certain.

Body:
I'm sorry if this question has been answered before, but I've looked around and I can't really understand the explanation as to why I'm getting this error.

From what I understand I'm asking if a statement is true and then if it is I'm asking it to return an expression. And apparently I'm not allowed to get #t/#f answers and expressions? I'm not sure. Could someone help me understand.

This is my code.

(define (piecewise x)
  (define pi 3.142)
  (cond
    ((> x (* pi 2)) (- x (* 2 pi)))
    ((or ( > x (* pi -1) (= x ( * -1 pi)))) (sin x))
    ((or ( < x (* 2 pi)) (= x (* 2 pi))) (sin x))
    (else (- (- 1 x) pi))))

Body:
If I may, if we take all of the suggestions and use them to simplify the code a bit, we might get the following:

(define (piecewise x)
  (let* ((pi 3.142)
         (tau (* 2 pi)))
    (cond
     ((> x tau)
      (- x tau))
     ((or (>= x (- pi))
          (<= x tau))
      (sin x))
     (else (+ x pi)))))

This runs without errors under both Racket and Guile. Whether it computes the function correctly, only the OP can say for certain.


问:
Removing a sentence from a text in dataframe column
I want to format a text-column in the dataframe in a following way:

In entries where the last character of a string is a colon ":" I want to delete the last sentence in this text i.e. a substring starting from a character after the last ".", "?" or "!" and finishing on that colon.

Example df:

```<code>index    text
1        Trump met with Putin. Learn more here:
2        New movie by Christopher Nolan! Watch here:
3        Campers: Get ready to stop COVID-19 in its tracks!
4        London was building a bigger rival to the Eiffel Tower. Then it all went wrong.
</code>```

after formatting should look like this:

```<code>index    text
1        Trump met with Putin.
2        New movie by Christopher Nolan!
3        Campers: Get ready to stop COVID-19 in its tracks!
4        London was building a bigger rival to the Eiffel Tower. Then it all went wrong.
</code>```

答:
Using sent_tokenize from the NLTK tokenize API which IMO is the idiomatic way of tokenizing sentences

```<code>from nltk.tokenize import sent_tokenize
(df['text'].map(nltk.sent_tokenize)
           .map(lambda sent: ' '.join([s for s in sent if not s.endswith(':')])))

index
1                                Trump met with Putin.
2                      New movie by Christopher Nolan.
3    Campers: Get ready to stop COVID-19 in its tra...
4    London was building a bigger rival to the Eiff...
Name: text, dtype: object
</code>```

You might have to handle NaNs appropriately with a preceeding fillna('') call if your column contains those.

In list form the output looks like this:

```<code>['Trump met with Putin.',
 'New movie by Christopher Nolan.',
 'Campers: Get ready to stop COVID-19 in its tracks!',
 'London was building a bigger rival to the Eiffel Tower. Then it all went wrong.']
</code>```

Note that NLTK needs to be pip-installed.

Body:
I want to format a text-column in the dataframe in a following way:

In entries where the last character of a string is a colon ":" I want to delete the last sentence in this text i.e. a substring starting from a character after the last ".", "?" or "!" and finishing on that colon.

Example df:

index    text
1        Trump met with Putin. Learn more here:
2        New movie by Christopher Nolan! Watch here:
3        Campers: Get ready to stop COVID-19 in its tracks!
4        London was building a bigger rival to the Eiffel Tower. Then it all went wrong.

after formatting should look like this:

index    text
1        Trump met with Putin.
2        New movie by Christopher Nolan!
3        Campers: Get ready to stop COVID-19 in its tracks!
4        London was building a bigger rival to the Eiffel Tower. Then it all went wrong.

Body:
Using sent_tokenize from the NLTK tokenize API which IMO is the idiomatic way of tokenizing sentences

from nltk.tokenize import sent_tokenize
(df['text'].map(nltk.sent_tokenize)
           .map(lambda sent: ' '.join([s for s in sent if not s.endswith(':')])))

index
1                                Trump met with Putin.
2                      New movie by Christopher Nolan.
3    Campers: Get ready to stop COVID-19 in its tra...
4    London was building a bigger rival to the Eiff...
Name: text, dtype: object

You might have to handle NaNs appropriately with a preceeding fillna('') call if your column contains those.

In list form the output looks like this:

['Trump met with Putin.',
 'New movie by Christopher Nolan.',
 'Campers: Get ready to stop COVID-19 in its tracks!',
 'London was building a bigger rival to the Eiffel Tower. Then it all went wrong.']

Note that NLTK needs to be pip-installed.


问:
Image.open() cannot identify image file in python script file
I am trying to execute this script

```<code>from PIL import Image
im = Image.open("image.jpg")
nx, ny = im.size
</code>```

It is working fine when I run it in python shell

```<code>pytesser_v0.0.1]#env python
>>> from PIL import Image
>>> im = Image.open("image.jpg")
<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=46x24 at 0x7FA4688F16D0>
</code>```

but when I put it in a some test.py file and run it like python test.py
I am getting this error

```<code>File "test1.py", line 17, in <module>
    im = Image.open("image.jpg")
  File "/usr/local/python.2.7.11/lib/python2.7/site-packages/PIL/Image.py", line 2309, in open
    % (filename if filename else fp))
IOError: cannot identify image file 'image.jpg'
</code>```

please help me with this issue, Thanks

PS: Earlier I installed PIL from Imaging-1.1.7 setup.py, later I installed Pillow, I think the problem was in the mutual presence of the PIL and Pillow library on the machine.

答:
Seems like PIL library haven't fixed this bug yet.

Here is my solution:
Open image using OpenCV library, then convert it to PIL image

```<code>from PIL import Image
import cv2

image_path = 'Folder/My_picture.jpg'

# read image using cv2 as numpy array
cv_img = cv2.imread(image_path)

# convert the color (necessary)
cv_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB)

# read as PIL image in RGB
pil_img = Image.fromarray(cv_img).convert('RGBA')
</code>```

Then you can operate with it as with a regular PIL image object.

ContentLicense: CC BY-SA 3.0

Body:
I am trying to execute this script

from PIL import Image
im = Image.open("image.jpg")
nx, ny = im.size

It is working fine when I run it in python shell

pytesser_v0.0.1]#env python
>>> from PIL import Image
>>> im = Image.open("image.jpg")
<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=46x24 at 0x7FA4688F16D0>

but when I put it in a some test.py file and run it like python test.py
I am getting this error

File "test1.py", line 17, in <module>
    im = Image.open("image.jpg")
  File "/usr/local/python.2.7.11/lib/python2.7/site-packages/PIL/Image.py", line 2309, in open
    % (filename if filename else fp))
IOError: cannot identify image file 'image.jpg'

please help me with this issue, Thanks

PS: Earlier I installed PIL from Imaging-1.1.7 setup.py, later I installed Pillow, I think the problem was in the mutual presence of the PIL and Pillow library on the machine.

Body:
Seems like PIL library haven't fixed this bug yet.

Here is my solution:
Open image using OpenCV library, then convert it to PIL image

from PIL import Image
import cv2

image_path = 'Folder/My_picture.jpg'

# read image using cv2 as numpy array
cv_img = cv2.imread(image_path)

# convert the color (necessary)
cv_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB)

# read as PIL image in RGB
pil_img = Image.fromarray(cv_img).convert('RGBA')

Then you can operate with it as with a regular PIL image object.


问:
Blazor WASM: getting sibling components to communicate in order to update data
I have a page component and within it a breadcrumbs component and a business data component that displays all of the businesses for that page based on a category alias it is passed through the route.

Some of the breadcrumb links direct the user to another routable/page component and these work fine. However, some of them require a refresh of the business data component and it's these I'm having an issue with.

I've tried creating a service with a event that the breadcrumbs component can invoke when a link is clicked and the data component can subscribe to (following this post), but I can't get that to work as the return type is wrong when I try and call GetBusinesses as a result.

Here is the front end of my page component:

```<code>@if (breadcrumbs != null)
    {
        <Breadcrumbs Items="breadcrumbs"></Breadcrumbs>
    }

<BrowseByBusiness Alias="@Alias"></BrowseByBusiness>
</code>```

I set up my breadcrumbs like so (the Alias on the API call is a route parameter):

```<code>protected async override Task OnInitializedAsync()
        {
            categoryDto = await _publicClient.Client.GetFromJsonAsync<CategoryDto>($"api/Categories/GetCategoryByAlias/{Alias}");

            breadcrumbs = new List<BreadcrumbItem>
            {
                new BreadcrumbItem("Browse By Category", "/browse-by-category"),
                new BreadcrumbItem(categoryDto.Name, $"/browse-by-category/{categoryDto.Alias}"),
            };

            if (categoryDto.ParentCategory.Name != null)
            {
                breadcrumbs.Insert(1, new BreadcrumbItem(categoryDto.ParentCategory.Name, $"/browse-by-category/{categoryDto.ParentCategory.Alias}"));
            }
        }
</code>```

My BrowseByBusiness component:

```<code>@foreach (var businessDto in businessesDto)
            {
                <Animate Animation="Animations.Fade" Easing="Easings.Ease" DurationMilliseconds="2000">
                    <BusinessCard businessDto="businessDto"></BusinessCard>
                </Animate>
            }

@code {

[Inject] IBusinessHttpRepository _businessRepo { get; set; }

public MetaData metaData = new MetaData();
IEnumerable<BusinessDto> businessesDto;

protected async override Task OnInitializedAsync()
        {
            await GetBusinesses();
        }

private async Task GetBusinesses()
        {
            var pagingResponse = await _businessRepo.GetBusinessesByCategory(Alias, businessParameters);
            businessesDto = pagingResponse.Items;
            metaData = pagingResponse.MetaData;
        }
}
</code>```

My Breadcrumbs component:

```<code><div class="flex-row border-bottom pb-2">
    @foreach (var item in Items)
    {
        if (item.Equals(Last))
        {
            <span class="me-1">@item.Name</span>
        }
        else
        {
            <a class="me-1" href="@item.Url">@item.Name </a>

            <span class="me-1">/</span>
        }
    }
</div>

@code {
    [Parameter] public List<BreadcrumbItem> Items { get; set; }

    private BreadcrumbItem Last;

    protected async override Task OnInitializedAsync()
    {
        Last = Items.Last();
    }
}
</code>```

I'm using Blazor WASM and .net 6.

答:
I recently had a similar need and ended up rolling my own (extremely simple) message broker. You can see full details in this blog post, but the short story is that you add a message broker class (which in my blog post has a silly name, but should really be called something like MessageBroker)...

public class SoupDragon {
  public Action<Widget> NewWidget;

  public void RaiseNewWidget(Widget w) =>
    NewWidget?.Invoke(w);
}
```
<p>You then register this as a service, inject it into the component that is to send the message, and use it follows...</p>
<pre class="lang-cs prettyprint-override"><code>_soupDragon.RaiseNewWidget(newWidget);
</code>```

The component that is to pick up the message would inject a soup dragon, and hook up a method to catch the message. Whilst you can do this with a lambda, for reasons explained in more detail over there, you are best off hooking up to a method...

_soupDragon.NewWidget += HandleNewWidget;
```

One nice thing about this approach is that if you're doing server-side Blazor, you get communication between different users for free by making the message broker static.

Body:
I have a page component and within it a breadcrumbs component and a business data component that displays all of the businesses for that page based on a category alias it is passed through the route.

Some of the breadcrumb links direct the user to another routable/page component and these work fine. However, some of them require a refresh of the business data component and it's these I'm having an issue with.

I've tried creating a service with a event that the breadcrumbs component can invoke when a link is clicked and the data component can subscribe to (following this post), but I can't get that to work as the return type is wrong when I try and call GetBusinesses as a result.

Here is the front end of my page component:

@if (breadcrumbs != null)
    {
        <Breadcrumbs Items="breadcrumbs"></Breadcrumbs>
    }

<BrowseByBusiness Alias="@Alias"></BrowseByBusiness>

I set up my breadcrumbs like so (the Alias on the API call is a route parameter):

protected async override Task OnInitializedAsync()
        {
            categoryDto = await _publicClient.Client.GetFromJsonAsync<CategoryDto>($"api/Categories/GetCategoryByAlias/{Alias}");

            breadcrumbs = new List<BreadcrumbItem>
            {
                new BreadcrumbItem("Browse By Category", "/browse-by-category"),
                new BreadcrumbItem(categoryDto.Name, $"/browse-by-category/{categoryDto.Alias}"),
            };

            if (categoryDto.ParentCategory.Name != null)
            {
                breadcrumbs.Insert(1, new BreadcrumbItem(categoryDto.ParentCategory.Name, $"/browse-by-category/{categoryDto.ParentCategory.Alias}"));
            }
        }

My BrowseByBusiness component:

@foreach (var businessDto in businessesDto)
            {
                <Animate Animation="Animations.Fade" Easing="Easings.Ease" DurationMilliseconds="2000">
                    <BusinessCard businessDto="businessDto"></BusinessCard>
                </Animate>
            }

@code {

[Inject] IBusinessHttpRepository _businessRepo { get; set; }

public MetaData metaData = new MetaData();
IEnumerable<BusinessDto> businessesDto;

protected async override Task OnInitializedAsync()
        {
            await GetBusinesses();
        }

private async Task GetBusinesses()
        {
            var pagingResponse = await _businessRepo.GetBusinessesByCategory(Alias, businessParameters);
            businessesDto = pagingResponse.Items;
            metaData = pagingResponse.MetaData;
        }
}

My Breadcrumbs component:

    @foreach (var item in Items)
    {
        if (item.Equals(Last))
        {
            @item.Name
        }
        else
        {
            @item.Name

            /
        }
    }

@code {
    [Parameter] public List<BreadcrumbItem> Items { get; set; }

    private BreadcrumbItem Last;

    protected async override Task OnInitializedAsync()
    {
        Last = Items.Last();
    }
}

I'm using Blazor WASM and .net 6.

Body:
I recently had a similar need and ended up rolling my own (extremely simple) message broker. You can see full details in this blog post, but the short story is that you add a message broker class (which in my blog post has a silly name, but should really be called something like MessageBroker)...

public class SoupDragon {
  public Action<Widget> NewWidget;

  public void RaiseNewWidget(Widget w) =>
    NewWidget?.Invoke(w);
}

You then register this as a service, inject it into the component that is to send the message, and use it follows...

_soupDragon.RaiseNewWidget(newWidget);

The component that is to pick up the message would inject a soup dragon, and hook up a method to catch the message. Whilst you can do this with a lambda, for reasons explained in more detail over there, you are best off hooking up to a method...

_soupDragon.NewWidget += HandleNewWidget;

One nice thing about this approach is that if you're doing server-side Blazor, you get communication between different users for free by making the message broker static.


问:
What is the best way to download a file with a speed limit using NodeJS?
I am trying to figure out the best way to download files with a speed limit using NodeJS's builtin HTTPS module. (There is a fully working python implementation of what I am trying to do at the bottom.) I have written two different functions and both of them seem to get the job as expected.

download1 function, checks whether the speed limit has been exceeded in the current second and if so, pauses the download and creates a timeout that gets triggered at the end of that second that resumes the download.

download2 however, instead of creating a timeout, creates an interval that gets triggered once every 1000 miliseconds and resumes the download if it has been paused.

I was wondering which one of these two approaches is better or if I should go about it with a whole diffent approach.

Here are the functions:

export const download1 = (url: string, fileName: string, speedLimitInKb: number) => {
    return new Promise((resolve, _reject) => {
        https.get(url, res => {
            const stream = fs.createWriteStream(fileName);
            let totalSize = 0;
            let size = 0;
            let speedLimit = kbToBytes(speedLimitInKb);
            let startDate: number;
            let lastSecond = Date.now();

            res.pipe(stream);

            res.once("resume", () => {
                startDate = Date.now();
                console.log(`Started at ${new Date(startDate)}`)
            })

            res.on("data", (chunk) => {
                size += chunk.length;
                const now = Date.now();
                if (now - lastSecond > 1000) {
                    lastSecond = Date.now();
                    totalSize += size;
                    size = 0;
                } else if (size >= speedLimit) {
                    res.pause();
                    setTimeout(() => res.resume(), 1000 - (now - lastSecond));
                }
            });

            res.on("resume", () => {
                lastSecond = Date.now();
                totalSize += size;
                size = 0;
            })

            res.on("end", () => {
                const elapsed = (Date.now() - startDate) / 1000;
                totalSize += size
                stream.end();
                console.log(`${bytesToMb(totalSize)} mb of data downloaded in ${elapsed} seconds with a speed of ${bytesToKb(totalSize) / elapsed}`)
                resolve(undefined);
            });

            res.on("error", console.log);
        })
    })
};
```
<pre class="lang-js prettyprint-override"><code>export const download2 = (url: string, fileName: string, speedLimitInKb: number) => {
    return new Promise((resolve, _reject) => {
        https.get(url, res => {
            const stream = fs.createWriteStream(fileName);
            let totalSize = 0;
            let size = 0;
            let speedLimit = kbToBytes(speedLimitInKb);
            let startDate: number;
            res.pipe(stream);

            res.once("resume", () => {
                startDate = Date.now();
                console.log(`Started at ${new Date(startDate)}`)
            })

            const interval = setInterval(() => {
                if (res.isPaused()) {
                    res.resume();
                }
                totalSize += size;
                size = 0;
            }, 1000);

            res.on("data", (chunk) => {
                size += chunk.length;
                if (size >= speedLimit) {
                    res.pause();
                }
            });

            res.on("end", () => {
                clearInterval(interval);
                const elapsed = (Date.now() - startDate) / 1000;
                totalSize += size
                stream.end();
                console.log(`${bytesToMb(totalSize)} mb of data downloaded in ${elapsed} seconds with a speed of ${bytesToKb(totalSize) / elapsed}`)
                resolve(undefined);
            });

            res.on("error", console.log);
        });
    })
}
</code>```

Additional functions:

export const bytesToKb = (bytes: number) => bytes / 1024;
export const kbToMb = (kb: number) => kb / 1024;
export const kbToBytes = (kb: number) => kb * 1024;
export const mbToKb = (mb: number) => mb * 1024;
export const mbToBytes = (mb: number) => mb * 1024 * 1024;
export const bytesToMb = (bytes: number) => bytes / 1024 / 1024;
export const bytesToGb = (bytes: number) => bytes / 1024 / 1024 / 1024;
export const secondsToMs = (seconds: number) => seconds * 1000;
export const msToSeconds = (ms: number) => ms / 1000;
```
<p>I have written a Python version of what I am trying to achieve and this works with any speed limit and file size. I would like to figure out how I can implement this in nodejs:</p>
<pre class="lang-py prettyprint-override"><code>import requests
import time

def download(url, file_name, speed_limit_in_kb):
    start = time.time()
    size = 0
    total_size = 0
    with open(file_name, "wb") as f:
        with requests.get(url, stream=True) as res:
            last_second = time.time()
            for part in res.iter_content(1024):
                f.write(part)
                total_size += len(part)
                size += len(part)
                offset = time.time() - last_second
                if offset > 1:
                    size = 0
                    last_second = time.time()
                elif size > (1024 * speed_limit_in_kb):
                    time.sleep(1 - offset)
                    size = 0
                    last_second = time.time()
    elapsed = time.time() - start
    print(f"{total_size / 1024 / 1024} mb of data downloaded in {elapsed} seconds with a speed of {total_size / 1024 / elapsed}")
</code>```

答:
This type of question is bound to get opinionated answers. Personally, I would use nodejs' built-in streams capabilities to do the throttling. Observations using this approach:

Minimal code

The code relies on (nodejs) library code rather than custom code

High performance. Minimal overhead, also wrt. memory

CON: the code seems complex for those unfamiliar with streams

import fs from "fs";
import https from "https";
import stream from "stream";
import util from "util";

async function downloadWithBackpressure(url, filename, byteRate) {
    let totalBytesDownloaded = 0;
    const timeBeforeStart = Date.now();

    await util.promisify(stream.pipeline)(

        // Start the download stream
        await new Promise(resolve => https.get(url, resolve)),

        // Throttle data by combining setTimeout with a stream.Transform
        new stream.Transform({
            transform: async (chunk, encoding, next) => {
                // Accumulate the total number of bytes received
                totalBytesDownloaded += chunk.byteLength;

                // Sleep to throttle towards desired transfer speed
                const sleepMs = Math.max(0, (totalBytesDownloaded / byteRate * 1000) - Date.now() + timeBeforeStart);
                sleepMs && await new Promise(resolve => setTimeout(resolve, sleepMs));

                // Propagate the chunk to the stream writable
                next(null, chunk);
            }
        }),

        // Save the file to disk
        fs.createWriteStream(filename)
    );
}
```

Body:
I am trying to figure out the best way to download files with a speed limit using NodeJS's builtin HTTPS module. (There is a fully working python implementation of what I am trying to do at the bottom.) I have written two different functions and both of them seem to get the job as expected.

download1 function, checks whether the speed limit has been exceeded in the current second and if so, pauses the download and creates a timeout that gets triggered at the end of that second that resumes the download.

download2 however, instead of creating a timeout, creates an interval that gets triggered once every 1000 miliseconds and resumes the download if it has been paused.

I was wondering which one of these two approaches is better or if I should go about it with a whole diffent approach.

Here are the functions:

export const download1 = (url: string, fileName: string, speedLimitInKb: number) => {
    return new Promise((resolve, _reject) => {
        https.get(url, res => {
            const stream = fs.createWriteStream(fileName);
            let totalSize = 0;
            let size = 0;
            let speedLimit = kbToBytes(speedLimitInKb);
            let startDate: number;
            let lastSecond = Date.now();

            res.pipe(stream);

            res.once("resume", () => {
                startDate = Date.now();
                console.log(`Started at ${new Date(startDate)}`)
            })

            res.on("data", (chunk) => {
                size += chunk.length;
                const now = Date.now();
                if (now - lastSecond > 1000) {
                    lastSecond = Date.now();
                    totalSize += size;
                    size = 0;
                } else if (size >= speedLimit) {
                    res.pause();
                    setTimeout(() => res.resume(), 1000 - (now - lastSecond));
                }
            });

            res.on("resume", () => {
                lastSecond = Date.now();
                totalSize += size;
                size = 0;
            })

            res.on("end", () => {
                const elapsed = (Date.now() - startDate) / 1000;
                totalSize += size
                stream.end();
                console.log(`${bytesToMb(totalSize)} mb of data downloaded in ${elapsed} seconds with a speed of ${bytesToKb(totalSize) / elapsed}`)
                resolve(undefined);
            });

            res.on("error", console.log);
        })
    })
};

export const download2 = (url: string, fileName: string, speedLimitInKb: number) => {
    return new Promise((resolve, _reject) => {
        https.get(url, res => {
            const stream = fs.createWriteStream(fileName);
            let totalSize = 0;
            let size = 0;
            let speedLimit = kbToBytes(speedLimitInKb);
            let startDate: number;
            res.pipe(stream);

            res.once("resume", () => {
                startDate = Date.now();
                console.log(`Started at ${new Date(startDate)}`)
            })

            const interval = setInterval(() => {
                if (res.isPaused()) {
                    res.resume();
                }
                totalSize += size;
                size = 0;
            }, 1000);

            res.on("data", (chunk) => {
                size += chunk.length;
                if (size >= speedLimit) {
                    res.pause();
                }
            });

            res.on("end", () => {
                clearInterval(interval);
                const elapsed = (Date.now() - startDate) / 1000;
                totalSize += size
                stream.end();
                console.log(`${bytesToMb(totalSize)} mb of data downloaded in ${elapsed} seconds with a speed of ${bytesToKb(totalSize) / elapsed}`)
                resolve(undefined);
            });

            res.on("error", console.log);
        });
    })
}

Additional functions:

export const bytesToKb = (bytes: number) => bytes / 1024;
export const kbToMb = (kb: number) => kb / 1024;
export const kbToBytes = (kb: number) => kb * 1024;
export const mbToKb = (mb: number) => mb * 1024;
export const mbToBytes = (mb: number) => mb * 1024 * 1024;
export const bytesToMb = (bytes: number) => bytes / 1024 / 1024;
export const bytesToGb = (bytes: number) => bytes / 1024 / 1024 / 1024;
export const secondsToMs = (seconds: number) => seconds * 1000;
export const msToSeconds = (ms: number) => ms / 1000;

I have written a Python version of what I am trying to achieve and this works with any speed limit and file size. I would like to figure out how I can implement this in nodejs:

import requests
import time

def download(url, file_name, speed_limit_in_kb):
    start = time.time()
    size = 0
    total_size = 0
    with open(file_name, "wb") as f:
        with requests.get(url, stream=True) as res:
            last_second = time.time()
            for part in res.iter_content(1024):
                f.write(part)
                total_size += len(part)
                size += len(part)
                offset = time.time() - last_second
                if offset > 1:
                    size = 0
                    last_second = time.time()
                elif size > (1024 * speed_limit_in_kb):
                    time.sleep(1 - offset)
                    size = 0
                    last_second = time.time()
    elapsed = time.time() - start
    print(f"{total_size / 1024 / 1024} mb of data downloaded in {elapsed} seconds with a speed of {total_size / 1024 / elapsed}")


答:
lets do it with regex to have more problems

```<code>df.text = df.text.str.replace(r"(?<=[.!?])[^.!?]*:\s*$", "", regex=True)
</code>```

now df.text.tolist() is

```<code>['Trump met with Putin.',
 'New movie by Christopher Nolan!',
 'Campers: Get ready to stop COVID-19 in its tracks!',
 'London was building a bigger rival to the Eiffel Tower. Then it all went wrong.',
 "I don't want to do a national lockdown again. If #coronavirus continues to 'progress' in the UK."]
</code>```

variable lookbehind ftw

On regex:

```<code>(?<=[.!?])
</code>```

This is a "lookbehind". It doesnt physically match anything but asserts something, which is that there must be something before what follows this. That something happens to be a character class here [.!?] which means either . or ! or ?.

```<code>[^.!?]*
</code>```

Again we have a character class with square brackets. But now we have a caret ^ as the first which means that we want everything except those in the character class. So any character other than . or ! or ? will do.

The * after the character class is 0-or-more quantifier. Meaning, the "any character but .?!" can be found as many times as possible.

So far, we start matching either . or ? or !, and this character is behind a stream of characters which could be "anything but .?!". So we assured we match after the last sentence with this "anything but" because it can't match .?! on the way anymore.

```<code>:\s*$
</code>```

With :, we say that the 0-or-more stream above is to stop whenever it sees : (if ever; if not, no replacement happens as desired).

The \s* after it is to allow some possible (again, 0 or more due to *) spaces (\s means space) after the :. You can remove that if you are certain there shall not be any space after :.

Lastly we have $: this matches the end of string (nothing physical, but positional). So we are sure that the string ends with : followed optionally by some spaces.

Title: Removing a sentence from a text in dataframe column

Body:
lets do it with regex to have more problems

df.text = df.text.str.replace(r"(?<=[.!?])[^.!?]*:\s*$", "", regex=True)

now df.text.tolist() is

['Trump met with Putin.',
 'New movie by Christopher Nolan!',
 'Campers: Get ready to stop COVID-19 in its tracks!',
 'London was building a bigger rival to the Eiffel Tower. Then it all went wrong.',
 "I don't want to do a national lockdown again. If #coronavirus continues to 'progress' in the UK."]

variable lookbehind ftw

On regex:

(?<=[.!?])

This is a "lookbehind". It doesnt physically match anything but asserts something, which is that there must be something before what follows this. That something happens to be a character class here [.!?] which means either . or ! or ?.

[^.!?]*

Again we have a character class with square brackets. But now we have a caret ^ as the first which means that we want everything except those in the character class. So any character other than . or ! or ? will do.

The * after the character class is 0-or-more quantifier. Meaning, the "any character but .?!" can be found as many times as possible.

So far, we start matching either . or ? or !, and this character is behind a stream of characters which could be "anything but .?!". So we assured we match after the last sentence with this "anything but" because it can't match .?! on the way anymore.

:\s*$

With :, we say that the 0-or-more stream above is to stop whenever it sees : (if ever; if not, no replacement happens as desired).

The \s* after it is to allow some possible (again, 0 or more due to *) spaces (\s means space) after the :. You can remove that if you are certain there shall not be any space after :.

Lastly we have $: this matches the end of string (nothing physical, but positional). So we are sure that the string ends with : followed optionally by some spaces.


问:
nginx to flask doesn't preserve path
With Nginx I am forwarding request to flask app to serve some cert files.

custom_list.html

```<code>    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Files</title>
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"
              integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">

        <style type="text/css">
            table {
                font-family: arial, sans-serif;
                border-collapse: collapse;
                width: 100%;
            }

            td, th {
                border: 1px solid #dddddd;
                text-align: left;
                padding: 8px;
            }

            tr:nth-child(even) {
                background-color: #dddddd;
            }
        </style>

    </head>
    <body>

    <div class="container">

        <div class="row">
            <div align="center" class="col-lg-12">
                <h2 class="page-header">Files</h2>
            </div>
            <table>
                <tr>
                    <th>Name</th>
                    <th>Expiry</th>
                </tr>

                {% for file in files %}
                <tr>
                    <td><a href=" {{ url_for('send_image',filename=file.name) }}">{{ file.name }}</a></td>
                    <td>{{ file.exp }}</td>
                    <td></td>
                </tr>

                {% endfor %}
            </table>
        </div>
    </div>
    {% if error %}
    <div class="alert">
        <strong>Error : </strong> {{ error }}
    </div>
    {% endif %}
    </div>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"
            integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS"
            crossorigin="anonymous"></script>
    </body>
    </html>
</code>```

app.py

```<code>    import datetime
    import os
    import os.path as op
    from OpenSSL import crypto as c
    from flask import Flask, render_template, send_from_directory

    app = Flask(__name__, static_folder='')

    @app.route('/', methods=['Get', 'POST'])
    def index():
        files_details = []
        for base, dirs, files in os.walk('files'):
            for file in files:
                if file.split(".")[-1] == "crt" or file.split(".")[-1] == "base":
                    f = open("files/base.crt", "r")
                    print()
                    cert = c.load_certificate(c.FILETYPE_PEM, f.read())
                    exp = datetime.datetime.strptime(cert.get_notAfter().decode("utf-8"), "%Y%m%d%H%M%SZ").strftime(
                        "%Y-%m-%d-%H:%M:%S")
                    files_details.append({"name": file,
                                          "exp": exp})
                else:
                    files_details.append({"name": file, "exp": "N/A"})

            for fil in files_details:
                print(fil.get('name'))

            return render_template("custom_list.html", files=files_details, test="test")

    @app.route('/flask/files/<filename>')
    def send_image(filename):
        return send_from_directory(f"files/", filename)

    if __name__ == '__main__':
        app.run(host='0.0.0.0', port=5000, debug=True)
</code>```

Following is Nginx Config

```<code>    upstream base-cert {
        server base-cert:5000;
    }

    server {
        listen         80 default_server;
        server_name    localhost;
        keepalive_timeout 70;
        gzip on;
        gzip_disable "msie6";
        gzip_vary on;
        gzip_proxied any;
        gzip_comp_level 6;
        gzip_buffers 16 8k;
        gzip_http_version 1.1;
        gzip_types text/plain text/css application/json application/x-javascript application/javascript text/xml application/xml application/xml+rss text/javascript;

        ....

        location /utility/base-cert/ {
            proxy_pass http://base-cert;
        }
    }

</code>```

I am can access https://example.com/utility/base-cert. But when I click on some file to download it, path is changes in a browser to https://example.com/files/ca.crt.

It should be https://example.com/utility/base-cert/files/ca.crt

What I am missing here ?

答:
For a quick fix you can add the /utility/base-cert/ prefix to the endpoints, so the generated URLs will have it as well.

Or you can set the SCRIPT_NAME WSGI environment variable that sets the "root" URL of the app. However it is ignored by Flask bultin server, so you have to use a WSGI server, e.g. gunicorn:

```<code>gunicorn --env SCRIPT_NAME=/utility/base-cert --bind 0.0.0.0:5000 app:app
</code>```

Title: nginx to flask doesn't preserve path

Body:
With Nginx I am forwarding request to flask app to serve some cert files.

custom_list.html

    <!DOCTYPE html>

        <meta charset="UTF-8">
        <title>Files</title>
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"
              integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">

Files

                    Name
                    Expiry

                {% for file in files %}

                    {{ file.name }}
                    {{ file.exp }}

                {% endfor %}

    {% if error %}

        Error :  {{ error }}

    {% endif %}

app.py

    import datetime
    import os
    import os.path as op
    from OpenSSL import crypto as c
    from flask import Flask, render_template, send_from_directory

    app = Flask(__name__, static_folder='')

    @app.route('/', methods=['Get', 'POST'])
    def index():
        files_details = []
        for base, dirs, files in os.walk('files'):
            for file in files:
                if file.split(".")[-1] == "crt" or file.split(".")[-1] == "base":
                    f = open("files/base.crt", "r")
                    print()
                    cert = c.load_certificate(c.FILETYPE_PEM, f.read())
                    exp = datetime.datetime.strptime(cert.get_notAfter().decode("utf-8"), "%Y%m%d%H%M%SZ").strftime(
                        "%Y-%m-%d-%H:%M:%S")
                    files_details.append({"name": file,
                                          "exp": exp})
                else:
                    files_details.append({"name": file, "exp": "N/A"})

            for fil in files_details:
                print(fil.get('name'))

            return render_template("custom_list.html", files=files_details, test="test")

    @app.route('/flask/files/<filename>')
    def send_image(filename):
        return send_from_directory(f"files/", filename)

    if __name__ == '__main__':
        app.run(host='0.0.0.0', port=5000, debug=True)

Following is Nginx Config

    upstream base-cert {
        server base-cert:5000;
    }

    server {
        listen         80 default_server;
        server_name    localhost;
        keepalive_timeout 70;
        gzip on;
        gzip_disable "msie6";
        gzip_vary on;
        gzip_proxied any;
        gzip_comp_level 6;
        gzip_buffers 16 8k;
        gzip_http_version 1.1;
        gzip_types text/plain text/css application/json application/x-javascript application/javascript text/xml application/xml application/xml+rss text/javascript;

        ....

        location /utility/base-cert/ {
            proxy_pass http://base-cert;
        }
    }

I am can access https://example.com/utility/base-cert. But when I click on some file to download it, path is changes in a browser to https://example.com/files/ca.crt.

It should be https://example.com/utility/base-cert/files/ca.crt

What I am missing here ?

Body:
For a quick fix you can add the /utility/base-cert/ prefix to the endpoints, so the generated URLs will have it as well.

Or you can set the SCRIPT_NAME WSGI environment variable that sets the "root" URL of the app. However it is ignored by Flask bultin server, so you have to use a WSGI server, e.g. gunicorn:

gunicorn --env SCRIPT_NAME=/utility/base-cert --bind 0.0.0.0:5000 app:app


问:
vuejs for triggering dropdown show
I want the dropdown to be opened when ul is clicked on the menu I want, in the same way, when the 2nd dropdown is clicked, the open dropdown will be closed.</p>
```<code><template>
    <li>
        <MenuLink
            :link="items"
            :key="items.name"
            @click.stop="clickShow()"
        />
        <ul class="children" v-if="hasChild" :class="open ? 'show' : 'hidden'">
            <MenuItems
                v-for="subItem in items.children"
                :key="subItem.name"
                :items="subItem"
            />
        </ul>
    </li>

</template>
<script>

export default {
    name: 'MenuItems',
    components: {MenuLink},
    props: {
        items: {type: Object, required: true},
        level: {
            type: Number,
            default: 0
        }
    },
data() {
        return {
            childrenCount: 0,
            active: false,
            show: null,
            open: false,
        };
    },
</code>```

答:
This is a I found that worked for me.
Also, I used the vue composition api, which I highly recommend using.

```<code><template>
  <ul v-if="showDropdownX">
    <li>This is X</li>
    <li>This is X</li>
    <li>This is X</li>
  </ul>
  <button @click="handleShowX">Toggle dropdown X</button>

  <ul v-if="showDropdownY">
    <li>This is Y</li>
    <li>This is Y</li>
    <li>This is Y</li>
  </ul>
  <button @click="handleShowY">Toggle Dropdown Y</button>
</template>

<script>
import { ref } from "@vue/reactivity";
export default {
  setup() {
    const showDropdownX = ref(false);
    const showDropdownY = ref(false);

    const handleShowX = () => {
      showDropdownX.value = !showDropdownX.value;
      showDropdownY.value = false;
    };
    const handleShowY = () => {
      showDropdownY.value = !showDropdownY.value;
      showDropdownX.value = false;
    };

    return {
      showDropdownX,
      showDropdownY,
      handleShowX,
      handleShowY,
    };
  },
};
</script>
</code>```

I hope this works for you, I haven't used the exact same code which you used, but I think my example is great to understand the concept of v-if

Edit:

Now the other dropdown will also disappear when you click on one of them.

Title: vuejs for triggering dropdown show

Body:
I want the dropdown to be opened when ul is clicked on the menu I want, in the same way, when the 2nd dropdown is clicked, the open dropdown will be closed.

<template>

        <MenuLink
            :link="items"
            :key="items.name"
            @click.stop="clickShow()"
        />

            <MenuItems
                v-for="subItem in items.children"
                :key="subItem.name"
                :items="subItem"
            />

</template>

Body:
This is a I found that worked for me.
Also, I used the vue composition api, which I highly recommend using.

<template>
  <ul v-if="showDropdownX">
    <li>This is X</li>
    <li>This is X</li>
    <li>This is X</li>
  </ul>
  <button @click="handleShowX">Toggle dropdown X</button>

  <ul v-if="showDropdownY">
    <li>This is Y</li>
    <li>This is Y</li>
    <li>This is Y</li>
  </ul>
  <button @click="handleShowY">Toggle Dropdown Y</button>
</template>

<script>
import { ref } from "@vue/reactivity";
export default {
  setup() {
    const showDropdownX = ref(false);
    const showDropdownY = ref(false);

    const handleShowX = () => {
      showDropdownX.value = !showDropdownX.value;
      showDropdownY.value = false;
    };
    const handleShowY = () => {
      showDropdownY.value = !showDropdownY.value;
      showDropdownX.value = false;
    };

    return {
      showDropdownX,
      showDropdownY,
      handleShowX,
      handleShowY,
    };
  },
};
</script>

I hope this works for you, I haven't used the exact same code which you used, but I think my example is great to understand the concept of v-if

Edit:

Now the other dropdown will also disappear when you click on one of them.


问:
Clicking hamburger icon on Toolbar does not open Navigation Drawer
I have a simple android.support.v7.widget.Toolbar and all I am trying to do is to open a NavigationDrawer by pressing the "hamburger" icon in the top left corner. The "hamburger" button is visible, and when I start to pull from the left I see the animation on the button but pressing the button does not open/close the NavigationDrawer as I expect. I have followed the [Google Documentation][1] and still am not able to figure this out. Sorry for any confusion, below is the simplified code I am currently attempting to use:

```<code>public class MainActivity extends AppCompatActivity implements
    View.OnClickListener,
    GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

    Toolbar toolbar = (Toolbar) findViewById(R.id.my_toolbar);
    setSupportActionBar(toolbar);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    toolbar.setNavigationOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Log.d("NICK", "button button button..................");
        }
    });

        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer);
        NavigationView n = (NavigationView) findViewById(R.id.nav);
        mDrawerLayout.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                Log.d("NICK", "button button button..................");
            }
        });

        //mDrawerLayout.setDrawerListener(mDrawerToggle);
        n.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(MenuItem menuItem) {
                switch (menuItem.getItemId()) {
                    ////.......

                }
                mDrawerLayout.closeDrawers();  // CLOSE DRAWER
                return true;
            }
        });

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    Log.d("NICK","CWECNEWKVNERIPNVIEWNFVIPEWNVIPEWNVPIEWNVPIEWNVPIEWNVPIRWNVPRWVPO");
    switch (item.getItemId()) {
        case android.R.id.home:
            mDrawerLayout.openDrawer(GravityCompat.START);  // OPEN DRAWER
            Log.d("NICK","CWECNEWKVNERIPNVIEWNFVIPEWNVIPEWNVPIEWNVPIEWNVPIEWNVPIRWNVPRWVPO");
            return true;

    }
           return super.onOptionsItemSelected(item);

}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    mDrawerToggle.onConfigurationChanged(newConfig);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.drawer, menu);
    return true;
}

}
</code>```

}

And as it is I do not get any of the log debug statements when running.

This is essentially the issue I have: https://stackoverflow.com/a/26636045/1489990. I've followed this and it just doesn't work.

It is my understanding that setNavigationOnClickListener is called when the hamburger icon is pressed, and this is where I am focusing my efforts is to get the event handled properly because when I press the button I do not get my log statement. Let me know if this idea is incorrect. https://developer.android.com/reference/android/widget/Toolbar.html#setNavigationOnClickListener(android.view.View.OnClickListener)

My Layouts:

ActivityMain.xml

```<code><RelativeLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/d"
android:background="@drawable/home_wall">

<android.support.v7.widget.Toolbar
    android:id="@+id/my_toolbar"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:minHeight="?attr/actionBarSize"
    android:background="?attr/colorPrimary"
    android:layout_marginBottom="10dp"
    app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
    android:layout_marginTop="25dp"

    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto" />

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:id="@+id/drawer"

    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <ImageView
        android:layout_width="fill_parent"
        android:layout_height="200dp"
        android:id="@+id/imageView"
        android:src="@drawable/trans2"
        android:layout_alignParentTop="true"
        android:layout_marginTop="10dp"
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        android:paddingBottom="300dp" />

    <RelativeLayout
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:id="@+id/d8"
        android:layout_alignParentTop="true"
        android:layout_alignLeft="@+id/imageView"
        android:layout_alignStart="@+id/imageView"
        android:paddingTop="0dp">

        <Button
            android:layout_width="75dp"
            android:layout_height="50dp"
            android:text="Gallery"
            android:id="@+id/save_button"
            android:background="#dd2c00" android:textColor="#fff"
            android:layout_below="@+id/Purchases"
            android:layout_toRightOf="@+id/start_button"
            android:layout_toEndOf="@+id/start_button" />
        <Button
            android:layout_width="125dp"
            android:layout_height="50dp"
            android:text="Store"
            android:id="@+id/Purchases"
            android:background="#ff6e40" android:textColor="#fff"
            android:layout_above="@+id/instructions_button6"
            android:layout_toLeftOf="@+id/start_button"
            android:layout_toStartOf="@+id/start_button"
            android:layout_marginBottom="98dp" />
        <Button
            android:layout_width="75dp"
            android:layout_height="50dp"
            android:text="Help"
            android:id="@+id/instructions_button6"
            android:background="#dd2c00" android:textColor="#fff"
            android:layout_alignParentBottom="true"
            android:layout_toLeftOf="@+id/start_button"
            android:layout_toStartOf="@+id/start_button"
            android:layout_marginLeft="5dp"
            android:layout_marginBottom="10dp" />
        <Button
            android:layout_width="75dp"
            android:layout_height="300dp"
            android:text="Start"
            android:id="@+id/start_button"
            android:background="#ff3d00"
            android:textColor="#fff"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true"
            android:layout_marginBottom="10dp" />
        <Button
            android:layout_width="125dp"
            android:layout_height="50dp"
            android:text="Achievements"
            android:id="@+id/Scores"
            android:background="#ff6e40" android:textColor="#fff"
            android:layout_alignTop="@+id/Purchases"
            android:layout_toRightOf="@+id/start_button"
            android:layout_toEndOf="@+id/start_button" />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Welcome to the quiz!"
            android:id="@+id/textView"
            android:textColor="#fff"
            android:textSize="20dp"
            android:layout_alignParentTop="true"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="70dp" />

        <!-- sign-in button -->
        <com.google.android.gms.common.SignInButton
            android:id="@+id/sign_in_button"
            android:layout_width="110dp"
            android:layout_height="50dp"
            android:layout_above="@+id/start_button"
            android:layout_centerHorizontal="true"
            android:visibility="visible" />

        <!-- sign-out button -->
        <Button
            android:id="@+id/sign_out_button"
            android:layout_width="125dp"
            android:layout_height="wrap_content"
            android:text="Sign Out"
            android:visibility="invisible"
            android:background="#dd4b39"
            android:textColor="#fff"
            android:layout_alignTop="@+id/sign_in_button"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="160dp" />

    </RelativeLayout>

    <android.support.design.widget.NavigationView
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:background="#fff"
        android:id="@+id/nav"

        app:headerLayout="@layout/drawer_header"
        app:menu="@menu/drawer"/>
</android.support.v4.widget.DrawerLayout>
</code>```

Drawer.xml:

```<code><menu xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_menu"
xmlns:app="http://schemas.android.com/apk/res-auto">

<item android:title="Google Play Games"

    android:icon="@drawable/ic_local_airport_white_48dp">
    <menu>
        <item
            android:id="@+id/Sign_in_drawer"

            android:icon="@drawable/games_controller_grey"
            android:title="Sign in" />
        <item
            android:id="@+id/ach"
            android:icon="@drawable/games_achievements"
            android:title="Achievements" />
    </menu>
</item>

<item android:title="Start a Quiz"

   android:icon="@drawable/ic_local_airport_white_48dp">
    <menu>
        <item
            android:id="@+id/quizStart25"

            android:icon="@drawable/ic_local_airport_white_48dp"
            android:title="25 Questions" />
        <item
            android:id="@+id/quizStart10"
            android:icon="@drawable/ic_local_airport_white_48dp"
            android:title="10 Questions" />
    </menu>
</item>

<group
    android:checkableBehavior="single">
    <item
        android:id="@+id/gallery"

        android:icon="@drawable/ic_photo_library_white_48dp"
        android:title="Gallery" />
    <item
        android:id="@+id/stats"
        android:icon="@drawable/ic_toc_white_48dp"
        android:title="Statistics" />
    <item
        android:id="@+id/store"
        android:icon="@drawable/ic_shop_white_48dp"
        android:title="Store" />
    <item
        android:id="@+id/settings"
        android:icon="@drawable/ic_settings_white_48dp"
        android:title="Settings" />
    <item
        android:id="@+id/about"
        android:icon="@drawable/ic_info_white_48dp"
        android:title="About" />

</group>

<item android:title="Support">
    <menu>
        <item
            android:id="@+id/help_drawer"
            android:icon="@drawable/ic_help_white_48dp"
            android:title="Help" />
        <item
            android:id="@+id/report"
            android:icon="@drawable/ic_report_problem_white_48dp"
            android:title="Contact Developer" />
        <item
            android:id="@+id/GPlusCommunity"
            android:icon="@drawable/btn_g_white_normal"
            android:title="Google+ Community" />

    </menu>
</item>
</code>```

答: I have found a simple solution to this problem is to call the setSupportActionBar(toolbar) method before the navigation drawer functions.</p>

Body:
I have a simple android.support.v7.widget.Toolbar and all I am trying to do is to open a NavigationDrawer by pressing the "hamburger" icon in the top left corner. The "hamburger" button is visible, and when I start to pull from the left I see the animation on the button but pressing the button does not open/close the NavigationDrawer as I expect. I have followed the [Google Documentation][1] and still am not able to figure this out. Sorry for any confusion, below is the simplified code I am currently attempting to use:

public class MainActivity extends AppCompatActivity implements
    View.OnClickListener,
    GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

    Toolbar toolbar = (Toolbar) findViewById(R.id.my_toolbar);
    setSupportActionBar(toolbar);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    toolbar.setNavigationOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Log.d("NICK", "button button button..................");
        }
    });

        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer);
        NavigationView n = (NavigationView) findViewById(R.id.nav);
        mDrawerLayout.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                Log.d("NICK", "button button button..................");
            }
        });

        //mDrawerLayout.setDrawerListener(mDrawerToggle);
        n.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(MenuItem menuItem) {
                switch (menuItem.getItemId()) {
                    ////.......

                }
                mDrawerLayout.closeDrawers();  // CLOSE DRAWER
                return true;
            }
        });

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    Log.d("NICK","CWECNEWKVNERIPNVIEWNFVIPEWNVIPEWNVPIEWNVPIEWNVPIEWNVPIRWNVPRWVPO");
    switch (item.getItemId()) {
        case android.R.id.home:
            mDrawerLayout.openDrawer(GravityCompat.START);  // OPEN DRAWER
            Log.d("NICK","CWECNEWKVNERIPNVIEWNFVIPEWNVIPEWNVPIEWNVPIEWNVPIEWNVPIRWNVPRWVPO");
            return true;

    }
           return super.onOptionsItemSelected(item);

}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    mDrawerToggle.onConfigurationChanged(newConfig);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.drawer, menu);
    return true;
}

}

}

And as it is I do not get any of the log debug statements when running.

This is essentially the issue I have: https://stackoverflow.com/a/26636045/1489990. I've followed this and it just doesn't work.

It is my understanding that setNavigationOnClickListener is called when the hamburger icon is pressed, and this is where I am focusing my efforts is to get the event handled properly because when I press the button I do not get my log statement. Let me know if this idea is incorrect. https://developer.android.com/reference/android/widget/Toolbar.html#setNavigationOnClickListener(android.view.View.OnClickListener)

My Layouts:

ActivityMain.xml

<RelativeLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/d"
android:background="@drawable/home_wall">

<android.support.v7.widget.Toolbar
    android:id="@+id/my_toolbar"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:minHeight="?attr/actionBarSize"
    android:background="?attr/colorPrimary"
    android:layout_marginBottom="10dp"
    app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
    android:layout_marginTop="25dp"

    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto" />

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:id="@+id/drawer"

    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <ImageView
        android:layout_width="fill_parent"
        android:layout_height="200dp"
        android:id="@+id/imageView"
        android:src="@drawable/trans2"
        android:layout_alignParentTop="true"
        android:layout_marginTop="10dp"
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        android:paddingBottom="300dp" />

    <RelativeLayout
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:id="@+id/d8"
        android:layout_alignParentTop="true"
        android:layout_alignLeft="@+id/imageView"
        android:layout_alignStart="@+id/imageView"
        android:paddingTop="0dp">

        <Button
            android:layout_width="75dp"
            android:layout_height="50dp"
            android:text="Gallery"
            android:id="@+id/save_button"
            android:background="#dd2c00" android:textColor="#fff"
            android:layout_below="@+id/Purchases"
            android:layout_toRightOf="@+id/start_button"
            android:layout_toEndOf="@+id/start_button" />
        <Button
            android:layout_width="125dp"
            android:layout_height="50dp"
            android:text="Store"
            android:id="@+id/Purchases"
            android:background="#ff6e40" android:textColor="#fff"
            android:layout_above="@+id/instructions_button6"
            android:layout_toLeftOf="@+id/start_button"
            android:layout_toStartOf="@+id/start_button"
            android:layout_marginBottom="98dp" />
        <Button
            android:layout_width="75dp"
            android:layout_height="50dp"
            android:text="Help"
            android:id="@+id/instructions_button6"
            android:background="#dd2c00" android:textColor="#fff"
            android:layout_alignParentBottom="true"
            android:layout_toLeftOf="@+id/start_button"
            android:layout_toStartOf="@+id/start_button"
            android:layout_marginLeft="5dp"
            android:layout_marginBottom="10dp" />
        <Button
            android:layout_width="75dp"
            android:layout_height="300dp"
            android:text="Start"
            android:id="@+id/start_button"
            android:background="#ff3d00"
            android:textColor="#fff"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true"
            android:layout_marginBottom="10dp" />
        <Button
            android:layout_width="125dp"
            android:layout_height="50dp"
            android:text="Achievements"
            android:id="@+id/Scores"
            android:background="#ff6e40" android:textColor="#fff"
            android:layout_alignTop="@+id/Purchases"
            android:layout_toRightOf="@+id/start_button"
            android:layout_toEndOf="@+id/start_button" />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Welcome to the quiz!"
            android:id="@+id/textView"
            android:textColor="#fff"
            android:textSize="20dp"
            android:layout_alignParentTop="true"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="70dp" />

        <com.google.android.gms.common.SignInButton
            android:id="@+id/sign_in_button"
            android:layout_width="110dp"
            android:layout_height="50dp"
            android:layout_above="@+id/start_button"
            android:layout_centerHorizontal="true"
            android:visibility="visible" />

        <Button
            android:id="@+id/sign_out_button"
            android:layout_width="125dp"
            android:layout_height="wrap_content"
            android:text="Sign Out"
            android:visibility="invisible"
            android:background="#dd4b39"
            android:textColor="#fff"
            android:layout_alignTop="@+id/sign_in_button"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="160dp" />

    </RelativeLayout>

    <android.support.design.widget.NavigationView
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:background="#fff"
        android:id="@+id/nav"

        app:headerLayout="@layout/drawer_header"
        app:menu="@menu/drawer"/>
</android.support.v4.widget.DrawerLayout>

Drawer.xml:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_menu"
xmlns:app="http://schemas.android.com/apk/res-auto">

<item android:title="Google Play Games"

    android:icon="@drawable/ic_local_airport_white_48dp">
    <menu>
        <item
            android:id="@+id/Sign_in_drawer"

            android:icon="@drawable/games_controller_grey"
            android:title="Sign in" />
        <item
            android:id="@+id/ach"
            android:icon="@drawable/games_achievements"
            android:title="Achievements" />
    </menu>
</item>

<item android:title="Start a Quiz"

   android:icon="@drawable/ic_local_airport_white_48dp">
    <menu>
        <item
            android:id="@+id/quizStart25"

            android:icon="@drawable/ic_local_airport_white_48dp"
            android:title="25 Questions" />
        <item
            android:id="@+id/quizStart10"
            android:icon="@drawable/ic_local_airport_white_48dp"
            android:title="10 Questions" />
    </menu>
</item>

<group
    android:checkableBehavior="single">
    <item
        android:id="@+id/gallery"

        android:icon="@drawable/ic_photo_library_white_48dp"
        android:title="Gallery" />
    <item
        android:id="@+id/stats"
        android:icon="@drawable/ic_toc_white_48dp"
        android:title="Statistics" />
    <item
        android:id="@+id/store"
        android:icon="@drawable/ic_shop_white_48dp"
        android:title="Store" />
    <item
        android:id="@+id/settings"
        android:icon="@drawable/ic_settings_white_48dp"
        android:title="Settings" />
    <item
        android:id="@+id/about"
        android:icon="@drawable/ic_info_white_48dp"
        android:title="About" />

</group>

<item android:title="Support">
    <menu>
        <item
            android:id="@+id/help_drawer"
            android:icon="@drawable/ic_help_white_48dp"
            android:title="Help" />
        <item
            android:id="@+id/report"
            android:icon="@drawable/ic_report_problem_white_48dp"
            android:title="Contact Developer" />
        <item
            android:id="@+id/GPlusCommunity"
            android:icon="@drawable/btn_g_white_normal"
            android:title="Google+ Community" />

    </menu>
</item>


问:
Changing the gradient color of `shap.summary_plot()` to specific 2 or 3 RGB gradient palette Colors
I have been trying to change the gradient palette colours from the shap.summary_plot() to the ones interested, exemplified in RGB.

To illustrate it, I have tried to use matplotlib to create my palette. However, it has not worked so far.
Could someone help me with that ?

This is what I have tried so far:
Creating an example with the iris dataset (No problem in here)

```<code>import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from sklearn import datasets
from sklearn.model_selection import train_test_split
import xgboost as xgb
import shap

# import some data to play with
iris = datasets.load_iris()
Y = pd.DataFrame(iris.target, columns = ["Species"])
X = pd.DataFrame(iris.data, columns = iris.feature_names)

X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.3, random_state=0, stratify=Y)

params = { # General Parameters
            'booster': 'gbtree',
            # Param for boosting
             'eta': 0.2,
             'gamma': 1,
             'max_depth': 5,
             'min_child_weight': 5,
             'subsample': 0.5,
             'colsample_bynode': 0.5,
             'lambda': 0,  #default = 0
             'alpha': 1,    #default = 1
            # Command line parameters
             'num_rounds': 10000,
            # Learning Task Parameters
             'objective': 'multi:softprob' #'multi:softprob'
             }

model = xgb.XGBClassifier(**params, verbose=0, cv=5 , )
# fitting the model
model.fit(X_train,np.ravel(Y_train), eval_set=[(X_test, np.ravel(Y_test))], early_stopping_rounds=20)
# Tree on XGBoost
explainerXGB = shap.TreeExplainer(model, data=X, model_output ="margin")
#recall one  can put "probablity"  then we explain the output of the model transformed
#into probability space (note that this means the SHAP values now sum to the probability output of the model).
shap_values_XGB_test = explainerXGB.shap_values(X_test)
shap_values_XGB_train = explainerXGB.shap_values(X_train)

shap.summary_plot(shap_values_XGB_train, X_train, )#color=cmap
</code>```

Until here if you run the code when should get the summary plot with the default colors. In order to change the default ones, I have tried to create my 2 color gradient palette as following:

```<code>from matplotlib import cm
from matplotlib.colors import ListedColormap, LinearSegmentedColormap

RGB_val = 255

color01= (0,150,200)  # Blue wanted
color04= (220,60,60)  # red wanted
Colors = [color01, color04]

# Creating a blue red palette transition for graphics
Colors= [(R/RGB_val,G/RGB_val,B/RGB_val) for idx, (R,G,B) in enumerate(Colors)]
n = 256

# Start of the creation of the gradient
Color01= ListedColormap(Colors[0], name='Color01', N=None)
Color04= ListedColormap(Colors[1], name='Color04', N=None)
top = cm.get_cmap(Color01,128)
bottom = cm.get_cmap(Color04,128)
newcolors = np.vstack((top(np.linspace(0, 1, 128)),
                       bottom(np.linspace(0, 1, 128))))

mymin0 = newcolors[0][0]
mymin1 = newcolors[0][1]
mymin2 = newcolors[0][2]
mymin3 = newcolors[0][3]
mymax0 = newcolors[255][0]
mymax1 = newcolors[255][1]
mymax2 = newcolors[255][2]
mymax3 = newcolors[255][3]

GradientBlueRed= [np.linspace(mymin0, mymax0,  n),
                   np.linspace(mymin1, mymax1,  n),
                   np.linspace(mymin2, mymax2,  n),
                   np.linspace(mymin3, mymax3,  n)]

GradientBlueRed_res =np.transpose(GradientBlueRed)

# End of the creation of the gradient

newcmp = ListedColormap(GradientBlueRed_res, name='BlueRed')

shap.summary_plot(shap_values_XGB_train, X_train, color=newcmp)
</code>```

But I haven't been able to get a change on the colors of the graphic. :

Can someone explain me how to make it for:

(A) 2 gradient color or
(B) 3 color gradient (specifying a color in the middle between the other 2) ?

Thank you so much for your time in advanced,

答:
I am not sure which version of SHAP you are using, but in version 0.4.0 (02-2022) summary plot has cmap parameter, so you can directly pass the cmap you build to it:</p>
```<code>    shap.summary_plot(shap_values, plot_type='dot', plot_size=(12, 6), cmap='hsv')

</code>```

Body:
I have been trying to change the gradient palette colours from the shap.summary_plot() to the ones interested, exemplified in RGB.

To illustrate it, I have tried to use matplotlib to create my palette. However, it has not worked so far.
Could someone help me with that ?

This is what I have tried so far:
Creating an example with the iris dataset (No problem in here)

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from sklearn import datasets
from sklearn.model_selection import train_test_split
import xgboost as xgb
import shap

# import some data to play with
iris = datasets.load_iris()
Y = pd.DataFrame(iris.target, columns = ["Species"])
X = pd.DataFrame(iris.data, columns = iris.feature_names)

X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.3, random_state=0, stratify=Y)

params = { # General Parameters
            'booster': 'gbtree',
            # Param for boosting
             'eta': 0.2,
             'gamma': 1,
             'max_depth': 5,
             'min_child_weight': 5,
             'subsample': 0.5,
             'colsample_bynode': 0.5,
             'lambda': 0,  #default = 0
             'alpha': 1,    #default = 1
            # Command line parameters
             'num_rounds': 10000,
            # Learning Task Parameters
             'objective': 'multi:softprob' #'multi:softprob'
             }

model = xgb.XGBClassifier(**params, verbose=0, cv=5 , )
# fitting the model
model.fit(X_train,np.ravel(Y_train), eval_set=[(X_test, np.ravel(Y_test))], early_stopping_rounds=20)
# Tree on XGBoost
explainerXGB = shap.TreeExplainer(model, data=X, model_output ="margin")
#recall one  can put "probablity"  then we explain the output of the model transformed
#into probability space (note that this means the SHAP values now sum to the probability output of the model).
shap_values_XGB_test = explainerXGB.shap_values(X_test)
shap_values_XGB_train = explainerXGB.shap_values(X_train)

shap.summary_plot(shap_values_XGB_train, X_train, )#color=cmap

Until here if you run the code when should get the summary plot with the default colors. In order to change the default ones, I have tried to create my 2 color gradient palette as following:

from matplotlib import cm
from matplotlib.colors import ListedColormap, LinearSegmentedColormap

RGB_val = 255

color01= (0,150,200)  # Blue wanted
color04= (220,60,60)  # red wanted
Colors = [color01, color04]

# Creating a blue red palette transition for graphics
Colors= [(R/RGB_val,G/RGB_val,B/RGB_val) for idx, (R,G,B) in enumerate(Colors)]
n = 256

# Start of the creation of the gradient
Color01= ListedColormap(Colors[0], name='Color01', N=None)
Color04= ListedColormap(Colors[1], name='Color04', N=None)
top = cm.get_cmap(Color01,128)
bottom = cm.get_cmap(Color04,128)
newcolors = np.vstack((top(np.linspace(0, 1, 128)),
                       bottom(np.linspace(0, 1, 128))))

mymin0 = newcolors[0][0]
mymin1 = newcolors[0][1]
mymin2 = newcolors[0][2]
mymin3 = newcolors[0][3]
mymax0 = newcolors[255][0]
mymax1 = newcolors[255][1]
mymax2 = newcolors[255][2]
mymax3 = newcolors[255][3]

GradientBlueRed= [np.linspace(mymin0, mymax0,  n),
                   np.linspace(mymin1, mymax1,  n),
                   np.linspace(mymin2, mymax2,  n),
                   np.linspace(mymin3, mymax3,  n)]

GradientBlueRed_res =np.transpose(GradientBlueRed)

# End of the creation of the gradient

newcmp = ListedColormap(GradientBlueRed_res, name='BlueRed')

shap.summary_plot(shap_values_XGB_train, X_train, color=newcmp)

But I haven't been able to get a change on the colors of the graphic. :

Can someone explain me how to make it for:

(A) 2 gradient color or
(B) 3 color gradient (specifying a color in the middle between the other 2) ?

Thank you so much for your time in advanced,

Body:
I am not sure which version of SHAP you are using, but in version 0.4.0 (02-2022) summary plot has cmap parameter, so you can directly pass the cmap you build to it:

    shap.summary_plot(shap_values, plot_type='dot', plot_size=(12, 6), cmap='hsv')


问:
Hide parent component when close button is clicked in angular
As stated I would like to hide the parent component when a button is clicked in the child. Comments with all capital letters show where I am trying to implement this functionality. Any help would be greatly appreciated.

child component.ts

```<code>export class CardComponent implements OnInit {

  //Event variable to display this cards details
  @Input()
    singleevent!:myevent;

  //SENDING BOOLEAN EVENT TO PARENT COMPONENT
  @Output()
  onRemoveClick!:EventEmitter<boolean>;

  constructor() { }
  ngOnInit(): void {
    //Initialize event to get from service layer
  }

  //FUNCTION FOR EVENT EMITTER TO EMIT BOOLEAN VALUE
  removeClick(){
    this.onRemoveClick.emit(true);
  }

}

</code>```

child component.html

```<code><div class="card text-center" style="width: 18rem;">
  <div class="card-header card-title">

    <!-- HERE IS THE BUTTON WITH THE REMOVE CLICK FUNCTION ATTATCHED -->
    <button type="button" class="btn-close" aria-label="Close" (click)="removeClick()"></button>
    <h3>{{singleevent.name}}</h3></div>
    <div class="card-body">
      <h5 class="card-text">Date: {{singleevent.date | date : 'shortDate' }}</h5>
      <h5 class="card-time"> Start time: {{singleevent.startTime}}</h5>
      <h5 *ngIf="singleevent.endTime !== null">{{singleevent.endTime}}</h5>
    </div>
</code>```

parent.ts

```<code>export class CardlistComponent implements OnInit {

  //events variable will be set to event service get request
  events:myevent[] = EVENTS;
  eventlist!:myevent[]

  constructor() { }

  ngOnInit(): void {
  }

  //FUNCITON I MAY NEED TO CALL IN PARENT HTML
  remove(value:boolean){
    if(value)
      return true;
    return false;
  }

}
</code>```

parent.html this is where I am confused how can I call the [hidden] attribute or use my output to hide the Child component I am rendering.

```<code><app-button (click) = "toggleEvent()" text="Add New Event" color="dodgerBlue"></app-button>
<div class="container" [hidden]="!toggleNewEvent">
    <app-newcard></app-newcard>
</div>
<div class = "container">
    <div class = "row" >
        <div class = "col-sm" *ngFor="let thisevent of events">

            //THIS IS THE EVENT I WANT TO HIDE WHEN THE BUTTON IN THIS CHILD IS CLICKED
            <app-card [singleevent]="thisevent"></app-card>
        </div>
    </div>
</div>
</code>```

答:
You are not catching your output in the parent html.
So first catch the onRemoveClick then when the emitter is triggered, its going to call remove with the value emitted.

```<code><app-card [singleevent]="thisevent" (onRemoveClick)="remove($event)"></app-card>
</code>```

Now remove is triggered but the value isnt passed anywhere in the parent component. Instead of randomly returning a boolean, you need to assign that value to a variable that is going to be used in the html to hide. SO lets say you have a new variable hideParent

```<code>hideParent: boolean = false;

  remove(value:boolean){
    this.hideParent = value;
  }
</code>```

Now you have whether or not the prent have to hide in a variable easily accessible from the html. The next step is to use that variable.

I dont know exactly what your are trying to hide but you just have to bind the [hidden]="hideParent"

Body:
As stated I would like to hide the parent component when a button is clicked in the child. Comments with all capital letters show where I am trying to implement this functionality. Any help would be greatly appreciated.

child component.ts

export class CardComponent implements OnInit {

  //Event variable to display this cards details
  @Input()
    singleevent!:myevent;

  //SENDING BOOLEAN EVENT TO PARENT COMPONENT
  @Output()
  onRemoveClick!:EventEmitter<boolean>;

  constructor() { }
  ngOnInit(): void {
    //Initialize event to get from service layer
  }

  //FUNCTION FOR EVENT EMITTER TO EMIT BOOLEAN VALUE
  removeClick(){
    this.onRemoveClick.emit(true);
  }

}

child component.html

    <button type="button" class="btn-close" aria-label="Close" (click)="removeClick()"></button>

{{singleevent.name}}

Date: {{singleevent.date | date : 'shortDate' }}

 Start time: {{singleevent.startTime}}

{{singleevent.endTime}}

parent.ts

export class CardlistComponent implements OnInit {

  //events variable will be set to event service get request
  events:myevent[] = EVENTS;
  eventlist!:myevent[]

  constructor() { }

  ngOnInit(): void {
  }

  //FUNCITON I MAY NEED TO CALL IN PARENT HTML
  remove(value:boolean){
    if(value)
      return true;
    return false;
  }

}

parent.html this is where I am confused how can I call the [hidden] attribute or use my output to hide the Child component I am rendering.

<app-button (click) = "toggleEvent()" text="Add New Event" color="dodgerBlue"></app-button>

    <app-newcard></app-newcard>

            //THIS IS THE EVENT I WANT TO HIDE WHEN THE BUTTON IN THIS CHILD IS CLICKED
            <app-card [singleevent]="thisevent"></app-card>

Body:
You are not catching your output in the parent html.
So first catch the onRemoveClick then when the emitter is triggered, its going to call remove with the value emitted.

<app-card [singleevent]="thisevent" (onRemoveClick)="remove($event)"></app-card>

Now remove is triggered but the value isnt passed anywhere in the parent component. Instead of randomly returning a boolean, you need to assign that value to a variable that is going to be used in the html to hide. SO lets say you have a new variable hideParent

hideParent: boolean = false;

  remove(value:boolean){
    this.hideParent = value;
  }

Now you have whether or not the prent have to hide in a variable easily accessible from the html. The next step is to use that variable.

I dont know exactly what your are trying to hide but you just have to bind the [hidden]="hideParent"


问:
Move di container into his own project in .NET Core
I'm building an API in .NET Core 3.1. I  try to decouple this project in the typical 3 layers. Instead of having an UI layer, I have the API project with the controllers. I also have a class library project for the logic, and another class library project as the data access layer.

I'm trying to use dependency injection over all projects. My problem is, that I have, until now, registered my interfaces and classes as services in the ConfigureServices method in startup.cs, in my API project.

But that would mean, that the logic, and the data access layer would reference the API project. To solve this, I thought, it would be the best, if I move the DI container into his own "mapping" class library project and reference this in all other projects. Would that be a good practice?

If yes, how could such a project look like, how to setup the container and how will it be instantiated in the API's project ConfigureServices method in startup.cs?

答:
But that would mean, that the logic, and the data access layer would
reference the API project

I don't think it should, just opposite, API project will be solution entry point, sole project which "knows" about all other dependencies and glue them together.

Other projects need to reference IServiceCollection Interface, which can be done by installing Microsoft.Extensions.DependencyInjection NuGet package.

Every project can introduce own "registration" method, which can be called by entry point.

```<code>// In Logic project
public IServiceCollection AddLogic()
{
    services.AddSingleton<MyLogic>();
    // Add other logic types

    return services;
}

// In Data project
public IServiceCollection AddDataAccess(string connectionString)
{
    services.AddTransient<IRepository, SqlRepository>();
    services.AddDbContext<MyDbContext>(o => o.UseSqlServer(connectionString));

    return services
}

// Startup
var connectionString = Configuration.GetConnectionString("MyDatabase");
services.AddLogic();
services.AddDataAccess(connectionString);
</code>```

Only way where other projects need to reference API project is when you are using some types from API project. If this the case, then move them to the project where they are going to be used or introduce another project which both API and other project can reference.

Body:
But that would mean, that the logic, and the data access layer would
reference the API project

I don't think it should, just opposite, API project will be solution entry point, sole project which "knows" about all other dependencies and glue them together.

Other projects need to reference IServiceCollection Interface, which can be done by installing Microsoft.Extensions.DependencyInjection NuGet package.

Every project can introduce own "registration" method, which can be called by entry point.

// In Logic project
public IServiceCollection AddLogic()
{
    services.AddSingleton<MyLogic>();
    // Add other logic types

    return services;
}

// In Data project
public IServiceCollection AddDataAccess(string connectionString)
{
    services.AddTransient<IRepository, SqlRepository>();
    services.AddDbContext<MyDbContext>(o => o.UseSqlServer(connectionString));

    return services
}

// Startup
var connectionString = Configuration.GetConnectionString("MyDatabase");
services.AddLogic();
services.AddDataAccess(connectionString);

Only way where other projects need to reference API project is when you are using some types from API project. If this the case, then move them to the project where they are going to be used or introduce another project which both API and other project can reference.


问:
Website not rendering properly on boss's computer / browser, but all others seem to work fine. Help?
I'm a university student, and just built my first website for an internship. We are approaching the launch of the site, however during my debugging process I've found that of all places, it doesn't work on my boss's machine and browser combination. She uses a Vista OS and internet explorer 7 for a browser. I know IE7 is outdated, but according to broswershots.org IE7 will still render the site mostly correct on an XP operating system.

The main page of the site is accessible here

Here are screenshots of what happens with the Vista/IE7 combo:

Please let me know what you think, as any ideas would be extremely helpful. Thanks!

答:
"IE7 will still render the site mostly correct"

Sadly, no. IE has a long history of being crap and ignoring web standards. IE6 was notorious for this. IE7 a pain. IE8 a bummer and IE9 is mostly now just a small annoyance.

Bottom line is that you likely have IE7 bugs appearing. It's not necessarily indicative to bad markup or CSS, but rather just problems with IE7.

The typical solution is to use IE conditional comments to render a unique class name to the BODY tag. You can then over-ride the standard CSS just for a particular version of IE7 to bend it into submission:

```<code><!--[if !IE]> -->
    <body>
<!--<![endif]-->
<!--[if gt IE 8]>
    <body id="IE9">
<![endif]-->
<!--[if IE 8]>
    <body id="IE8">
<![endif]-->
<!--[if IE 7]>
    <body id="IE7">
<![endif]-->
<!--[if lt IE 7]>
    <body id="IE6">
<![endif]-->
</code>```

And then in your css you can do this:

```<code>.myClass {...standard styles...}
#IE7 .myClass {...ugly hack just for IE7...}
#IE6 .myClass {...ugly hack just for IE6...}
</code>```

Body:
"IE7 will still render the site mostly correct"

Sadly, no. IE has a long history of being crap and ignoring web standards. IE6 was notorious for this. IE7 a pain. IE8 a bummer and IE9 is mostly now just a small annoyance.

Bottom line is that you likely have IE7 bugs appearing. It's not necessarily indicative to bad markup or CSS, but rather just problems with IE7.

The typical solution is to use IE conditional comments to render a unique class name to the BODY tag. You can then over-ride the standard CSS just for a particular version of IE7 to bend it into submission:

<!--[if !IE]> -->
    <body>
<!--<![endif]-->
<!--[if gt IE 8]>
    <body id="IE9">
<![endif]-->
<!--[if IE 8]>
    <body id="IE8">
<![endif]-->
<!--[if IE 7]>
    <body id="IE7">
<![endif]-->
<!--[if lt IE 7]>
    <body id="IE6">
<![endif]-->

And then in your css you can do this:

.myClass {...standard styles...}
#IE7 .myClass {...ugly hack just for IE7...}
#IE6 .myClass {...ugly hack just for IE6...}