问:
Understanding git conflicts
I think I might be misunderstanding something about how git handles things, and, therefore, I'm facing some rather annoying conflicts.

I start a new branch A, from master, and start creating new files. Eventually, from branch A, I create branch B, and start working on that as well. A branch A continues to be developed, B needs the changes made in branch A, so I merge A into B, and continue working on both of them.

Times goes on, branch A continues to be developed, until it is merged into master. At this point, I think that, now it has been merged into master, I can do a simply merge master into B, and get all changes from A, and from everyone else as well.

Problem is, now that I'm trying to do that, I'm getting multiple conflicts of "Both added", "Both modified", and such - but on files I haven't changed. I totally understand the conflicts in the files I changed - I caused them, I know it full well.

Thinking my explanation my get confusing, I ventured into Google Slides and created this "amazing" drawing to illustrate my scenario (in which the arrows represent merges, as in "merged master into A", unless they point to the first commit in the branch - in which case they mean "branched off from here"; that is, pretty standard git notation, apart from the arrow direction - not sure here):

Regarding files other people changed, I don't understand why are they listed as conflicts. That is, there is a file which has been changed by the time I created branch A, and that same file got changed again when I tried to merge master into B. Sure, branch B still has a super old version of that given file, but, still, shouldn't git recognize that they have not been changed in my commits, and just overwrite them, or whatever it does? What am I missing here?

EDIT: just to clarify, I'm the sole contributor of both branches A and B.

答:
Your graph drawing is very pretty, but it's rather misleading.

Let's start with a question: which branch are the blue commits on?

This is a trick question.  They're not on a branch, they're on several branches, plural.  If you say they're on branch A, well, that's true, but they're also on master and most of them are also on branch B.

In your drawing, there are no identifiers for each commit.  This makes them hard to talk about: I could say "the second-from-left grey commit" or "the rightmost blue commit", but that's kind of unwieldy, so let me redraw the graph as text, using single uppercase letters in each commit.  I also won't use arrows here as they're too hard to do in text.

```<code>A--B--C--D--E--F--G--H--I--J--K--L   <-- master
    \        \            /
     M--N--O--P--Q---R---S   <-- branch-A
         \        \
          T--U--V--W--X--Y--Å--Ø--Z   <-- branch-B
</code>```

That is, the tip commit of master is commit L.  The tip commit of branch-A is commit S.  The tip commit of branch-B is commit Z.

In Git, a branch name, like master, always points to one single commit.  You get your choice of which commit; the commit you select this way is the tip commit of the branch.  Any earlier commit that is reachable from this tip is also on the branch.  So by starting at L and working backwards—leftwards, in these drawings—following the arrows from commit to commit,1 we go from L to K, then from K to J.  But J is a merge commit: it has two parents, not just one.  So from J we go to both S and I.  From those two, we go to both H and R, and on to G and Q, and F and P, and E.  There are two ways to reach E but we only visit it once anyway.  From here we can go on to O and D, N and C, M and B, and A.  So that list of commits is the set of commits that is on master.

(Note that we cannot go from Q to W, though we can go the other way, from W to Q: all the arrows are one way, pointing backwards.)

The set of commits on branch-A starts with S and goes backwards to R, then Q, then P, then E and O and D and N and so on.  All of these commits are also on master.

The set of commits on branch-B starts at Z, moves back through Ø and Å and Y and X and W, then picks up both P and V, and then E and O and U, and so on.  There are thus four commits on branch-B that are not on any other branch.

1Technically, all of Git's internal arrows point backwards.  So you've drawn your arrows backwards by drawing them forwards.  This situation arises because commits are fully read-only: a parent can't know in advance what hash IDs its eventual children might have, but a child commit does know, in advance / at creation time, what parent hash IDs that child has.  So the arrows must point backwards.

(In order to move forwards, you tell Git where you want to end up, and then it moves backwards from there, to make sure that it can end up there from some other starting point.)

How git merge works, greatly abbreviated

When you run:

```<code>git checkout master
git merge branch-B
</code>```

Git must find the merge base commit of commits L and Z.  To do that, it works backwards, as most Git operations do, from these branch tip commits, to find the best shared commit: a commit that is reachable from both branch tips, and hence on both branches, but is "closest to the tips" as it were.  In this case, though it's perhaps not immediately obvious, that's commit Q.  Start at L, go back through K to J and down to S and then R and then Q.  Meanwhile, start at Z, go back to W and up to Q.  Commits P, E, O, and so on are all also on both branches, but commit Q is "better" because it is the last such commit: it is a descendant of all of those commits.

Git will now run two git diff commands internally.  This will compare the merge base—commit Q—vs the two branch tips:

```<code>git diff --find-renames <hash-of-Q> <hash-of-L>   # what we changed
git diff --find-renames <hash-of-Q> <hash-of-Z>   # what they changed
</code>```

In these two diff listings, if some file appears to be newly-created in both branch tips, you will get an add/add conflict for that file.  The file wasn't in Q, but it is in L and Z.

For files that are in all three commits, Git will attempt to combine any changes shown in the two sets of diffs.  Where these changes do not overlap (and don't "touch at the edges" either), Git can combine them.  Where they do overlap but those overlaps are exactly the same—cover the same original lines in Q, and make the same changes—Git can combine that by just taking one copy of the change.  All other overlaps result in merge conflicts.

Your job at this point is to resolve any and all conflicts, any way you like.  For instance, in the add/add whole-file conflicts, if the two files match, just pick either one's content.  If not, combine the two files somehow.  When you're done, write the final contents for each conflicted file into the index using git add.  This marks the index conflict as "resolved", and you can now run git merge --continue or git commit to complete the merge.2

2git merge --continue checks to make sure you're finishing a merge.  If not, it errors out.  If you are, it just runs git commit—so there's no real difference either way, unless you aren't actually finishing a conflicted merge.

Title: Understanding git conflicts

Body:
Your graph drawing is very pretty, but it's rather misleading.

Let's start with a question: which branch are the blue commits on?

This is a trick question.  They're not on a branch, they're on several branches, plural.  If you say they're on branch A, well, that's true, but they're also on master and most of them are also on branch B.

In your drawing, there are no identifiers for each commit.  This makes them hard to talk about: I could say "the second-from-left grey commit" or "the rightmost blue commit", but that's kind of unwieldy, so let me redraw the graph as text, using single uppercase letters in each commit.  I also won't use arrows here as they're too hard to do in text.

A--B--C--D--E--F--G--H--I--J--K--L   <-- master
    \        \            /
     M--N--O--P--Q---R---S   <-- branch-A
         \        \
          T--U--V--W--X--Y--Å--Ø--Z   <-- branch-B

That is, the tip commit of master is commit L.  The tip commit of branch-A is commit S.  The tip commit of branch-B is commit Z.

In Git, a branch name, like master, always points to one single commit.  You get your choice of which commit; the commit you select this way is the tip commit of the branch.  Any earlier commit that is reachable from this tip is also on the branch.  So by starting at L and working backwards—leftwards, in these drawings—following the arrows from commit to commit,1 we go from L to K, then from K to J.  But J is a merge commit: it has two parents, not just one.  So from J we go to both S and I.  From those two, we go to both H and R, and on to G and Q, and F and P, and E.  There are two ways to reach E but we only visit it once anyway.  From here we can go on to O and D, N and C, M and B, and A.  So that list of commits is the set of commits that is on master.

(Note that we cannot go from Q to W, though we can go the other way, from W to Q: all the arrows are one way, pointing backwards.)

The set of commits on branch-A starts with S and goes backwards to R, then Q, then P, then E and O and D and N and so on.  All of these commits are also on master.

The set of commits on branch-B starts at Z, moves back through Ø and Å and Y and X and W, then picks up both P and V, and then E and O and U, and so on.  There are thus four commits on branch-B that are not on any other branch.

1Technically, all of Git's internal arrows point backwards.  So you've drawn your arrows backwards by drawing them forwards.  This situation arises because commits are fully read-only: a parent can't know in advance what hash IDs its eventual children might have, but a child commit does know, in advance / at creation time, what parent hash IDs that child has.  So the arrows must point backwards.

(In order to move forwards, you tell Git where you want to end up, and then it moves backwards from there, to make sure that it can end up there from some other starting point.)

How git merge works, greatly abbreviated

When you run:

git checkout master
git merge branch-B

Git must find the merge base commit of commits L and Z.  To do that, it works backwards, as most Git operations do, from these branch tip commits, to find the best shared commit: a commit that is reachable from both branch tips, and hence on both branches, but is "closest to the tips" as it were.  In this case, though it's perhaps not immediately obvious, that's commit Q.  Start at L, go back through K to J and down to S and then R and then Q.  Meanwhile, start at Z, go back to W and up to Q.  Commits P, E, O, and so on are all also on both branches, but commit Q is "better" because it is the last such commit: it is a descendant of all of those commits.

Git will now run two git diff commands internally.  This will compare the merge base—commit Q—vs the two branch tips:

git diff --find-renames <hash-of-Q> <hash-of-L>   # what we changed
git diff --find-renames <hash-of-Q> <hash-of-Z>   # what they changed

In these two diff listings, if some file appears to be newly-created in both branch tips, you will get an add/add conflict for that file.  The file wasn't in Q, but it is in L and Z.

For files that are in all three commits, Git will attempt to combine any changes shown in the two sets of diffs.  Where these changes do not overlap (and don't "touch at the edges" either), Git can combine them.  Where they do overlap but those overlaps are exactly the same—cover the same original lines in Q, and make the same changes—Git can combine that by just taking one copy of the change.  All other overlaps result in merge conflicts.

Your job at this point is to resolve any and all conflicts, any way you like.  For instance, in the add/add whole-file conflicts, if the two files match, just pick either one's content.  If not, combine the two files somehow.  When you're done, write the final contents for each conflicted file into the index using git add.  This marks the index conflict as "resolved", and you can now run git merge --continue or git commit to complete the merge.2

2git merge --continue checks to make sure you're finishing a merge.  If not, it errors out.  If you are, it just runs git commit—so there's no real difference either way, unless you aren't actually finishing a conflicted merge.


来源: stackexchange

问:
How to Create a Method to save user input
I have the following view here where the user is able to input three different items: LockedOutBy, LockedOutFor, and LockedOutDate. I am having trouble creating a method within my view-model to allow the user to input these three items and once they hit 'ok', it will save the three items. Sorry if it is vague or if there is not enough info, please let me know if there is anything else needed.

Thank you.

View

```<code><TextBlock VerticalAlignment="Center" Margin="5,5" Grid.Column="0" Grid.Row="1" Text="Locked Out By:"/>
                        <TextBox Grid.Column="1" Grid.Row="1" Text="{Binding LockedOutBy, UpdateSourceTrigger=PropertyChanged}"/>

<TextBlock VerticalAlignment="Center" Margin="5,5" Grid.Column="0" Grid.Row="2" Text="Locked Out For:"/>
                        <TextBox Grid.Column="1" Grid.Row="2" Text="{Binding LockedOutFor, UpdateSourceTrigger=PropertyChanged}"/>

<TextBlock VerticalAlignment="Center" Margin="5,5" Grid.Column="0" Grid.Row="3" Text="Locked Out Date:"/>
                        <TextBox Grid.Column="1" Grid.Row="3" Text="{Binding LockedOutDate, UpdateSourceTrigger=PropertyChanged}"/>

<Button Command="{Binding Path=OKCommand}"
</code>```

View-Model

This is what I have so far in my view-model.

```<code>private string _LockedOutFor;
        public string LockedOutFor
        {
            get { return _LockedOutFor; }
            set
            {
                _LockedOutFor = value;
                OnPropertyChanged("OwnerName");
            }
        }

        private string _LockedOutBy;
        public string LockedOutBy
        {
            get { return _LockedOutBy; }
            set
            {
                _LockedOutBy = value;
                OnPropertyChanged("Street");
            }
        }

        private int _LockedOutDate;
        public int LockedOutDate
        {
            get { return _LockedOutDate; }
            set
            {
                _LockedOutDate = value;
                OnPropertyChanged("StreetOverflow");
            }
        }

public ICommand CancelCommand
        {
            get { return new RelayCommand(c => OnCancelLock()); }
        }

        public ICommand OKCommand
        {
            get { return new RelayCommand(c => OnOKLock()); }
        }

        protected void OnOKLock()
        {
            OnOK(LockedOutFor, LockedOutBy, LockedOutDate);
        }

        protected void OnCancelLock()
        {
            OnCancel();
        }
</code>```

答:
ANotifyPropertyChanged - base implementation for all of our view models

```<code>using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace SO60269403
{
    public abstract class ANotifyPropertyChanged : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void SetProperty<T>(ref T backingStore, T newValue, [CallerMemberName] string propertyName = "")
        {
            var areEqual = ReferenceEquals(backingStore, newValue);
            if (areEqual)
                return;
            backingStore = newValue;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
</code>```

LockedOutViewModel - our view model

```<code>namespace SO60269403
{
    public class LockedOutViewModel : ANotifyPropertyChanged
    {
        private string lockedOutBy;
        private string lockedOutFor;
        private int lockedOutDate;

        public string LockedOutBy { get => lockedOutBy; set => SetProperty(ref lockedOutBy, value); }
        public string LockedOutFor { get => lockedOutFor; set => SetProperty(ref lockedOutFor, value); }
        public int LockedOutDate { get => lockedOutDate; set => SetProperty(ref lockedOutDate, value); }
    }
}
</code>```

ACommand - base implementation for all of our commands

```<code>using System;
using System.Windows.Input;

namespace SO60269403
{
    public abstract class ACommand : ICommand
    {
        public event EventHandler CanExecuteChanged;

        public virtual bool CanExecute(object parameter) => true;

        public abstract void Execute(object parameter);
    }
}
</code>```

SaveCommand - our save command

```<code>namespace SO60269403
{
    public class SaveCommand : ACommand
    {
        public LockedOutViewModel LockedOutViewModel { get; set; }

        public override void Execute(object parameter)
        {
            //TODO
        }
    }
}
</code>```

MainWindow - a view to data-bind our view model and hook up our save command

```<code><Window
    x:Class="SO60269403.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:SO60269403">
    <Window.Resources>
        <local:LockedOutViewModel
            x:Key="LockedOutViewModel" />
    </Window.Resources>
    <Grid
        DataContext="{StaticResource LockedOutViewModel}">
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <TextBlock
            Grid.Row="0"
            Grid.Column="0">Locked Out By</TextBlock>
        <TextBlock
            Grid.Row="1"
            Grid.Column="0">Locked Out For</TextBlock>
        <TextBlock
            Grid.Row="2"
            Grid.Column="0">Locked Out Date</TextBlock>
        <TextBox
            Grid.Row="0"
            Grid.Column="1"
            Text="{Binding LockedOutBy}" />
        <TextBox
            Grid.Row="1"
            Grid.Column="1"
            Text="{Binding LockedOutFor}" />
        <TextBox
            Grid.Row="2"
            Grid.Column="1"
            Text="{Binding LockedOutDate}" />
        <StackPanel
            Grid.Row="3"
            Grid.Column="0"
            Grid.ColumnSpan="2"
            Orientation="Horizontal"
            HorizontalAlignment="Right">
            <StackPanel.Resources>
                <Style
                    TargetType="Button">
                    <Setter
                        Property="Width"
                        Value="100" />
                </Style>
            </StackPanel.Resources>
            <Button>Cancel</Button>
            <Button>
                <Button.Command>
                    <local:SaveCommand
                        LockedOutViewModel="{StaticResource LockedOutViewModel}" />
                </Button.Command>
                OK
            </Button>
        </StackPanel>
    </Grid>
</Window>
</code>```

if we put a breakpoint in SaveCommand.Execute then run the app, fill in some values and click the OK button, the debugger should break on our breakpoint and we can observe that the view model's properties match what we entered. this demonstrates that the data is in place ready to be saved.

ContentLicense: CC BY-SA 4.0

Body:
I have the following view here where the user is able to input three different items: LockedOutBy, LockedOutFor, and LockedOutDate. I am having trouble creating a method within my view-model to allow the user to input these three items and once they hit 'ok', it will save the three items. Sorry if it is vague or if there is not enough info, please let me know if there is anything else needed.

Thank you.

View

<TextBlock VerticalAlignment="Center" Margin="5,5" Grid.Column="0" Grid.Row="1" Text="Locked Out By:"/>
                        <TextBox Grid.Column="1" Grid.Row="1" Text="{Binding LockedOutBy, UpdateSourceTrigger=PropertyChanged}"/>

<TextBlock VerticalAlignment="Center" Margin="5,5" Grid.Column="0" Grid.Row="2" Text="Locked Out For:"/>
                        <TextBox Grid.Column="1" Grid.Row="2" Text="{Binding LockedOutFor, UpdateSourceTrigger=PropertyChanged}"/>

<TextBlock VerticalAlignment="Center" Margin="5,5" Grid.Column="0" Grid.Row="3" Text="Locked Out Date:"/>
                        <TextBox Grid.Column="1" Grid.Row="3" Text="{Binding LockedOutDate, UpdateSourceTrigger=PropertyChanged}"/>

<Button Command="{Binding Path=OKCommand}"

View-Model

This is what I have so far in my view-model.

private string _LockedOutFor;
        public string LockedOutFor
        {
            get { return _LockedOutFor; }
            set
            {
                _LockedOutFor = value;
                OnPropertyChanged("OwnerName");
            }
        }

        private string _LockedOutBy;
        public string LockedOutBy
        {
            get { return _LockedOutBy; }
            set
            {
                _LockedOutBy = value;
                OnPropertyChanged("Street");
            }
        }

        private int _LockedOutDate;
        public int LockedOutDate
        {
            get { return _LockedOutDate; }
            set
            {
                _LockedOutDate = value;
                OnPropertyChanged("StreetOverflow");
            }
        }

public ICommand CancelCommand
        {
            get { return new RelayCommand(c => OnCancelLock()); }
        }

        public ICommand OKCommand
        {
            get { return new RelayCommand(c => OnOKLock()); }
        }

        protected void OnOKLock()
        {
            OnOK(LockedOutFor, LockedOutBy, LockedOutDate);
        }

        protected void OnCancelLock()
        {
            OnCancel();
        }

Body:
ANotifyPropertyChanged - base implementation for all of our view models

using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace SO60269403
{
    public abstract class ANotifyPropertyChanged : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void SetProperty<T>(ref T backingStore, T newValue, [CallerMemberName] string propertyName = "")
        {
            var areEqual = ReferenceEquals(backingStore, newValue);
            if (areEqual)
                return;
            backingStore = newValue;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

LockedOutViewModel - our view model

namespace SO60269403
{
    public class LockedOutViewModel : ANotifyPropertyChanged
    {
        private string lockedOutBy;
        private string lockedOutFor;
        private int lockedOutDate;

        public string LockedOutBy { get => lockedOutBy; set => SetProperty(ref lockedOutBy, value); }
        public string LockedOutFor { get => lockedOutFor; set => SetProperty(ref lockedOutFor, value); }
        public int LockedOutDate { get => lockedOutDate; set => SetProperty(ref lockedOutDate, value); }
    }
}

ACommand - base implementation for all of our commands

using System;
using System.Windows.Input;

namespace SO60269403
{
    public abstract class ACommand : ICommand
    {
        public event EventHandler CanExecuteChanged;

        public virtual bool CanExecute(object parameter) => true;

        public abstract void Execute(object parameter);
    }
}

SaveCommand - our save command

namespace SO60269403
{
    public class SaveCommand : ACommand
    {
        public LockedOutViewModel LockedOutViewModel { get; set; }

        public override void Execute(object parameter)
        {
            //TODO
        }
    }
}

MainWindow - a view to data-bind our view model and hook up our save command

<Window
    x:Class="SO60269403.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:SO60269403">
    <Window.Resources>
        <local:LockedOutViewModel
            x:Key="LockedOutViewModel" />
    </Window.Resources>
    <Grid
        DataContext="{StaticResource LockedOutViewModel}">
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <TextBlock
            Grid.Row="0"
            Grid.Column="0">Locked Out By</TextBlock>
        <TextBlock
            Grid.Row="1"
            Grid.Column="0">Locked Out For</TextBlock>
        <TextBlock
            Grid.Row="2"
            Grid.Column="0">Locked Out Date</TextBlock>
        <TextBox
            Grid.Row="0"
            Grid.Column="1"
            Text="{Binding LockedOutBy}" />
        <TextBox
            Grid.Row="1"
            Grid.Column="1"
            Text="{Binding LockedOutFor}" />
        <TextBox
            Grid.Row="2"
            Grid.Column="1"
            Text="{Binding LockedOutDate}" />
        <StackPanel
            Grid.Row="3"
            Grid.Column="0"
            Grid.ColumnSpan="2"
            Orientation="Horizontal"
            HorizontalAlignment="Right">
            <StackPanel.Resources>
                <Style
                    TargetType="Button">
                    <Setter
                        Property="Width"
                        Value="100" />
                </Style>
            </StackPanel.Resources>
            <Button>Cancel</Button>
            <Button>
                <Button.Command>
                    <local:SaveCommand
                        LockedOutViewModel="{StaticResource LockedOutViewModel}" />
                </Button.Command>
                OK
            </Button>
        </StackPanel>
    </Grid>
</Window>

if we put a breakpoint in SaveCommand.Execute then run the app, fill in some values and click the OK button, the debugger should break on our breakpoint and we can observe that the view model's properties match what we entered. this demonstrates that the data is in place ready to be saved.


问:
Google Translation API id blocking ip address for too many requests
I'm setting up a Django Views that requests products data from an API, parse them with BeautifulSoup, apply the googletrans module and save the response into my Postgresql database.

Everything was working fine yesterday until suddenly, Google blocked access on my IP address for too many requests at once..

I just turned on my LTE to change my IP address and it worked.

But now, to make sure that it doesn't happen with this IP address again I need to find a way to call the googletrans API in batches or any other solution that would prevent me from getting blocked again.

This is my Views:

```<code>from bs4 import BeautifulSoup
from googletrans import Translator
import requests
import json

def api_data(request):
    if request.GET.get('mybtn'):  # to improve, == 'something':
        resp_1 = requests.get(
            "https://www.headout.com/api/public/v1/product/listing/list-by/city?language=fr&cityCode=PARIS&limit=5000&currencyCode=CAD",
            headers={
                "Headout-Auth": HEADOUT_PRODUCTION_API_KEY
            })
        resp_1_data = resp_1.json()
        base_url_2 = "https://www.headout.com/api/public/v1/product/get/"

        translator = Translator()

        for item in resp_1_data['items']:
            print('translating item {}'.format(item['id']))
            # concat ID to the URL string
            url = '{}{}'.format(base_url_2, item['id'] + '?language=fr')

            # make the HTTP request
            resp_2 = requests.get(
                url,
                headers={
                    "Headout-Auth": HEADOUT_PRODUCTION_API_KEY
                })
            resp_2_data = resp_2.json()

            descriptiontxt = resp_2_data['contentListHtml'][0]['html'][0:2040] + ' ...'

            #Parsing work
            soup = BeautifulSoup(descriptiontxt, 'lxml')
            parsed = soup.find('p').text

            #Translation doesn't work
            translation = translator.translate(parsed, dest='fr')

            titlename = item['name']
            titlefr = translator.translate(titlename, dest='fr')

            destinationname = item['city']['name']
            destinationfr = translator.translate(destinationname, dest='fr')

            Product.objects.get_or_create(
                title=titlefr.text,
                destination=destinationfr.text,
                description=translation.text,
                link=item['canonicalUrl'],
                image=item['image']['url']
            )

    return render(request, "form.html")
</code>```

How can I call the Google translation API in Batch? Or is there any other solution for that?

Please help.

EDIT

Based on @ddor254 where should I put the: time.sleep(2)?

This is what I came out with, is this okay?

```<code>  Product.objects.get_or_create(
      title=titlefr.text,
      destination=destinationfr.text,
      description=translation.text,
      link=item['canonicalUrl'],
      image=item['image']['url']
  )time.sleep(2) #here
</code>```

or like this:

```<code>resp_1 = requests.get(
            "https://www.headout.com/api/public/v1/product/listing/list-by/city?language=fr&cityCode=PARIS&limit=5000&currencyCode=CAD",
            headers={
                "Headout-Auth": HEADOUT_PRODUCTION_API_KEY
            }, time.sleep(2)) #here
</code>```

Just want to make sure that its the right way to do it before risking of getting this new IP also blocked.

答:
I have been blocked too because of many concurrent requests. Usually always gets blocked after 500 concurrent requests. What I did was to put a timeout of 60 seconds after every 100 concurrent requests. It may seem long, but it works. You could also achieve that with a 45 seconds timeout, but I set it to 60 just to make sure.

Here's an example

```<code>class GoogleAPI():

    def __init__(self):
        self.limit_before_timeout = 100
        self.timeout = 60

    def translate(self, source):
        translation = translator.translate(source, dest="ar")
        translation = translation.__dict__['text']
        if translation != "" and translation is not None:
            return translation

    def process(self):
        i = 0
        print("initiation")
        for t in list_of_data:
            if i < self.limit_before_timeout:
                i += 1
                self.translate(t)
            else:
                i = 0
                print("100 words added")
                time.sleep(self.timeout)
        print("All done")
</code>```

Body:
I'm setting up a Django Views that requests products data from an API, parse them with BeautifulSoup, apply the googletrans module and save the response into my Postgresql database.

Everything was working fine yesterday until suddenly, Google blocked access on my IP address for too many requests at once..

I just turned on my LTE to change my IP address and it worked.

But now, to make sure that it doesn't happen with this IP address again I need to find a way to call the googletrans API in batches or any other solution that would prevent me from getting blocked again.

This is my Views:

from bs4 import BeautifulSoup
from googletrans import Translator
import requests
import json

def api_data(request):
    if request.GET.get('mybtn'):  # to improve, == 'something':
        resp_1 = requests.get(
            "https://www.headout.com/api/public/v1/product/listing/list-by/city?language=fr&cityCode=PARIS&limit=5000&currencyCode=CAD",
            headers={
                "Headout-Auth": HEADOUT_PRODUCTION_API_KEY
            })
        resp_1_data = resp_1.json()
        base_url_2 = "https://www.headout.com/api/public/v1/product/get/"

        translator = Translator()

        for item in resp_1_data['items']:
            print('translating item {}'.format(item['id']))
            # concat ID to the URL string
            url = '{}{}'.format(base_url_2, item['id'] + '?language=fr')

            # make the HTTP request
            resp_2 = requests.get(
                url,
                headers={
                    "Headout-Auth": HEADOUT_PRODUCTION_API_KEY
                })
            resp_2_data = resp_2.json()

            descriptiontxt = resp_2_data['contentListHtml'][0]['html'][0:2040] + ' ...'

            #Parsing work
            soup = BeautifulSoup(descriptiontxt, 'lxml')
            parsed = soup.find('p').text

            #Translation doesn't work
            translation = translator.translate(parsed, dest='fr')

            titlename = item['name']
            titlefr = translator.translate(titlename, dest='fr')

            destinationname = item['city']['name']
            destinationfr = translator.translate(destinationname, dest='fr')

            Product.objects.get_or_create(
                title=titlefr.text,
                destination=destinationfr.text,
                description=translation.text,
                link=item['canonicalUrl'],
                image=item['image']['url']
            )

    return render(request, "form.html")

How can I call the Google translation API in Batch? Or is there any other solution for that?

Please help.

EDIT

Based on @ddor254 where should I put the: time.sleep(2)?

This is what I came out with, is this okay?

  Product.objects.get_or_create(
      title=titlefr.text,
      destination=destinationfr.text,
      description=translation.text,
      link=item['canonicalUrl'],
      image=item['image']['url']
  )time.sleep(2) #here

or like this:

resp_1 = requests.get(
            "https://www.headout.com/api/public/v1/product/listing/list-by/city?language=fr&cityCode=PARIS&limit=5000&currencyCode=CAD",
            headers={
                "Headout-Auth": HEADOUT_PRODUCTION_API_KEY
            }, time.sleep(2)) #here

Just want to make sure that its the right way to do it before risking of getting this new IP also blocked.

Body:
I have been blocked too because of many concurrent requests. Usually always gets blocked after 500 concurrent requests. What I did was to put a timeout of 60 seconds after every 100 concurrent requests. It may seem long, but it works. You could also achieve that with a 45 seconds timeout, but I set it to 60 just to make sure.

Here's an example

class GoogleAPI():

    def __init__(self):
        self.limit_before_timeout = 100
        self.timeout = 60

    def translate(self, source):
        translation = translator.translate(source, dest="ar")
        translation = translation.__dict__['text']
        if translation != "" and translation is not None:
            return translation

    def process(self):
        i = 0
        print("initiation")
        for t in list_of_data:
            if i < self.limit_before_timeout:
                i += 1
                self.translate(t)
            else:
                i = 0
                print("100 words added")
                time.sleep(self.timeout)
        print("All done")


问:
Can Eclipse refresh resources automatically?
Eclipse (3.4.2 with PyDev) deals with out-of-sync resources (files that have been edited outside of the IDE) differently from other IDEs that I've used, where only resources with editors open are considered out-of-sync.  In Eclipse, any resource can go out of sync.

This means that when I perform a search after any file has changed outside of Eclipse, I get an error dialog telling me that files are out of sync, even if they have no open editors.  As far as I can tell, there is no global refresh command, so I'm forced to read the project names (I have several projects) in the error dialog, and do a right-click + refresh for each of them.

I've checked the Refresh Automatically setting in Settings > General > Workspace, but this has no effect.  Is there any way to get Eclipse to always just load non-active resources from disk?

答:
For Starting up there is an option to automatically refresh files in

Window -> Preferences -> General -> Startup and Shutdown -> Refresh workspace on startup

Click it in order to have a "fresh" start in eclipse. :)

Version: Eclipse 4.12

ContentLicense: CC BY-SA 3.0


问:
jQuery - 2 different functions for 2 different submit buttons in one form
I have had a search around at other suggestions for what i want to do, but none seems to have what i need.

Basically i have a form with 2 submit buttons, i want one to save the data to the database, which i have done and works perfect ... the second submit button ( preview ) i need to open in a new window, take all the form data and display it on a form while leaving the previous page as it is ... if that makes sense.

I figure i cant do this with PHP as to get the post data it needs to basically reload a page ... i thought there might be a way with jQuery.

Any help?

答:
Of cours that it's possible with jQuery. All you need to do is to write two onClick functions (to each button). In first function simply call $("form_name").submit() and your data will be submited.

And in the second function open the dialog (you can use this http://jqueryui.com/demos/dialog/), get all data from the form and put it into dialog in the way you need them).
To get all data from your form you can user another jQuery function $("form_name").serialize(). Take look here: http://api.jquery.com/serialize/</p>


问:
How to identify a canceled event in Microsoft Graph REST API?
After I've canceled an event, I couldn't list it at List events anymore. But it still displaying to end user as subject "Canceled: User subject event". How can I use List events to identify this canceled event?</p>

答:
I just tried

```<code>https://graph.microsoft.com/v1.0/Users/xx/Calendar/Events/xx/instances
?startDateTime=2020-02-17&endDateTime=2020-03-01&isCancelled=true
</code>```

and what came back are all the non-cancelled events... Ditto isCancelled=false so the query is kind of working.

leaving off the &isCancelled=xx parameter returns all the events with the isCancelled attribute set to false for everything.

Body:
I just tried

https://graph.microsoft.com/v1.0/Users/xx/Calendar/Events/xx/instances
?startDateTime=2020-02-17&endDateTime=2020-03-01&isCancelled=true

and what came back are all the non-cancelled events... Ditto isCancelled=false so the query is kind of working.

leaving off the &isCancelled=xx parameter returns all the events with the isCancelled attribute set to false for everything.


问:
Drop observations once condition is met by multiple variables
I have the following data and used one of the existing answered questions to solve my data problem but could not get what I want. Here is what I have in my data

Amt1 is populated when the Evt_type is Fee

Amt2 is populated when the Evt_type is REF1/REF2

I don't want to display any observations after the last Flag='Y'

If there is no Flag='Y' then I want all the observations for that id (e.g. id=102)

I want to display if the next row for that id is a Fee followed by REF1/REF2 after flag='Y' (e.g. id=101) However I don't want if there is no REF1/REF2 (e.g.id=103)

Have:

```<code>       id   Date        Evt_Type   Flag   Amt1   Amt2
      101  2/2/2019      Fee              5
      101  2/3/2019      REF1      Y             5
      101  2/4/2019      Fee              10
      101  2/6/2019      REF2      Y             10
      101  2/7/2019      Fee               4
      101  2/8/2019      REF1
      102  2/2/2019      Fee              25
      102  2/2/2019      REF1      N      25
      103  2/3/2019      Fee              10
      103  2/4/2019      REF1      Y             10
      103  2/5/2019      Fee              10
</code>```

Want:

```<code>      id   Date        Evt_Type   Flag   Amt1   Amt2
     101  2/2/2019      Fee              5
     101  2/3/2019      REF1      Y             5
     101  2/4/2019      Fee              10
     101  2/6/2019      REF2      Y             10
     101  2/7/2019      Fee               4
     101  2/8/2019      REF1
     102  2/2/2019      Fee              25
     102  2/2/2019      REF1      N      25
     103  2/4/2019      REF1      Y             10
     103  2/5/2019      Fee              10
</code>```

I tried the following

```<code>data want;
    set have;
    by id Date;
    drop count;

    if (first.id or first.date) and FLAG='Y' then
        do;
            retain count;
            count=1;
            output;
            return;
        end;

    if count=1 and ((first.id or first.date) and Flag ne 'Y') then
        do;
            retain count;
            delete;
            return;
        end;
    output;
run;
</code>```

Any help is appreciated.

Thanks

答:
Here is one way</p>

```<code>data have;
input id $ Date : mmddyy10. Evt_Type $ Flag $ Amt1 Amt2;
format Date mmddyy10.;
infile datalines dsd missover;
datalines;
101,2/2/2019,Fee,,5,
101,2/3/2019,REF1,Y,,5
101,2/4/2019,Fee,,10,
101,2/6/2019,REF2,Y,,10
101,2/7/2019,Fee,,4,
102,2/2/2019,Fee,,25,
102,2/2/2019,REF1,N,25,
;

data want;
   do _N_ = 1 by 1 until (last.id);
      set have;
      by id;
      if flag = "Y" then _iorc_ = _N_;
   end;

   do _N_ = 1 to _N_;
      set have;
      if _N_ le _iorc_ then output;
   end;
   _iorc_=1e7;
run;
</code>```

Body:
I have the following data and used one of the existing answered questions to solve my data problem but could not get what I want. Here is what I have in my data

Amt1 is populated when the Evt_type is Fee

Amt2 is populated when the Evt_type is REF1/REF2

I don't want to display any observations after the last Flag='Y'

If there is no Flag='Y' then I want all the observations for that id (e.g. id=102)

I want to display if the next row for that id is a Fee followed by REF1/REF2 after flag='Y' (e.g. id=101) However I don't want if there is no REF1/REF2 (e.g.id=103)

Have:

       id   Date        Evt_Type   Flag   Amt1   Amt2
      101  2/2/2019      Fee              5
      101  2/3/2019      REF1      Y             5
      101  2/4/2019      Fee              10
      101  2/6/2019      REF2      Y             10
      101  2/7/2019      Fee               4
      101  2/8/2019      REF1
      102  2/2/2019      Fee              25
      102  2/2/2019      REF1      N      25
      103  2/3/2019      Fee              10
      103  2/4/2019      REF1      Y             10
      103  2/5/2019      Fee              10

Want:

      id   Date        Evt_Type   Flag   Amt1   Amt2
     101  2/2/2019      Fee              5
     101  2/3/2019      REF1      Y             5
     101  2/4/2019      Fee              10
     101  2/6/2019      REF2      Y             10
     101  2/7/2019      Fee               4
     101  2/8/2019      REF1
     102  2/2/2019      Fee              25
     102  2/2/2019      REF1      N      25
     103  2/4/2019      REF1      Y             10
     103  2/5/2019      Fee              10

I tried the following

data want;
    set have;
    by id Date;
    drop count;

    if (first.id or first.date) and FLAG='Y' then
        do;
            retain count;
            count=1;
            output;
            return;
        end;

    if count=1 and ((first.id or first.date) and Flag ne 'Y') then
        do;
            retain count;
            delete;
            return;
        end;
    output;
run;

Any help is appreciated.

Thanks

Body:
Here is one way

data have;
input id $ Date : mmddyy10. Evt_Type $ Flag $ Amt1 Amt2;
format Date mmddyy10.;
infile datalines dsd missover;
datalines;
101,2/2/2019,Fee,,5,
101,2/3/2019,REF1,Y,,5
101,2/4/2019,Fee,,10,
101,2/6/2019,REF2,Y,,10
101,2/7/2019,Fee,,4,
102,2/2/2019,Fee,,25,
102,2/2/2019,REF1,N,25,
;

data want;
   do _N_ = 1 by 1 until (last.id);
      set have;
      by id;
      if flag = "Y" then _iorc_ = _N_;
   end;

   do _N_ = 1 to _N_;
      set have;
      if _N_ le _iorc_ then output;
   end;
   _iorc_=1e7;
run;


问:
How to set first value in numpy array that meets a condition to 1 but not the rest
I want to set the max value in a numpy array equal to 1, and the rest of the values to 0, so that there is only one value equal to 1 in the new array.

Right now I'm doing this with:

```<code>new_arr = np.where(arr == np.max(arr), 1, 0)
</code>```

However, if there are multiple values in arr that are equal to np.max(arr) then there will be multiple values in new_arr equal to 1.
How do I make it so that there is only one value in new_arr equal to 1 (the first value equal to np.max(arr) seems like a fine option but not necessary).

答:
You can use:

```<code>new_arr = np.zeros(shape=arr.shape)
new_arr[np.unravel_index(np.argmax(arr),shape=arr.shape)] = 1
</code>```

This also works for multi-dimensional arrays. np.argmax gives the flattened index of the first instance of the max element, and np.unravel_index converts the flat index to the index based on the array shape.

Body:
I want to set the max value in a numpy array equal to 1, and the rest of the values to 0, so that there is only one value equal to 1 in the new array.

Right now I'm doing this with:

new_arr = np.where(arr == np.max(arr), 1, 0)

However, if there are multiple values in arr that are equal to np.max(arr) then there will be multiple values in new_arr equal to 1.
How do I make it so that there is only one value in new_arr equal to 1 (the first value equal to np.max(arr) seems like a fine option but not necessary).

Body:
You can use:

new_arr = np.zeros(shape=arr.shape)
new_arr[np.unravel_index(np.argmax(arr),shape=arr.shape)] = 1

This also works for multi-dimensional arrays. np.argmax gives the flattened index of the first instance of the max element, and np.unravel_index converts the flat index to the index based on the array shape.


问:
Angular 8, How to navigate to a common page, then navigate to my desired pag?
I am new to front end development. Imagine I have a menu page which has 3 options to navigate to:

Go to Arena.

Go to Dungeon.

Go to Battleground.

But if I click any of these 3 options I will jump to a common page let's say it is character picking:

/characterPicking

If we finished selection and click next, we will navigate to weapon picking:

/weaponPicking

After that finally we will jump to the page we want:

/arena, /dungeon or /battleground

```<code>{ path: '', component: MenuComponent },
{ path: 'arena', component: ArenaComponent },
{ path: 'dungeon', component: DungeonComponent},
{ path: 'battleground', component: BattlegroundComponent},
{ path: 'characterPicking', component: CharacterPickingComponent},
{ path: 'weaponPicking', component: WeaponPickingComponent},
{ path: '**', redirectTo: ''},
</code>```

If above is my rounting path. As you can see, character picking and weapon picking are common components. If I bind the path /characterPicking to the 3 options on menu page. And bind /weaponPicking to the Next Button on characterPicking page.
Then how to bind the path for the Next Button on weaponPicking page, how to let weapon picking page know which page should it go next? Arena/Dungeon/BattleGround ?

I hope I explained this clear..

答:
Okay, you have three buttons, but all of them navigate to the same path '/characterPicking'. I think you should manage the button click before navigate and store whitch button the user pressed.
Then the user pick his character and navigate to '/weaponPicking' and when he press the last next button you should read the option and navigate to the correct path between 'arena', 'dungeon' or 'battleground'.

Something like this i think:

```<code>@Component({
  selector: 'app-menu',
  template: `
    <button (click)="go('arena')">Arena</button>
    <button (click)="go('dungeon')">Dungeon</button>
    <button (click)="go('battlegroud')">Battleground</button>
  `,
  styles: []
})
export class MenuComponent {

  go(where){
    this.stateService.option = where;
    this.router.navigate(['characterPicking'])
  }
}
</code>```

And then in your WeaponPickingComponent can do something like this:

```<code>@Component({
  selector: 'app-weapon-picking',
  template: `
    <button (click)="next()">Next</button>
  `,
  styles: []
})
export class WeaponPickingComponent {

  next(){
    switch(this.stateService.option){
      case 'arena':
        this.router.navigate(['arena']);
        break;
      case 'dungeon':
        this.router.navigate(['dungeon']);
        break;
      case 'battlegroud':
        this.router.navigate(['battleground']);
        break;
    }
  }
}
</code>```

Body:
I am new to front end development. Imagine I have a menu page which has 3 options to navigate to:

Go to Arena.

Go to Dungeon.

Go to Battleground.

But if I click any of these 3 options I will jump to a common page let's say it is character picking:

/characterPicking

If we finished selection and click next, we will navigate to weapon picking:

/weaponPicking

After that finally we will jump to the page we want:

/arena, /dungeon or /battleground

{ path: '', component: MenuComponent },
{ path: 'arena', component: ArenaComponent },
{ path: 'dungeon', component: DungeonComponent},
{ path: 'battleground', component: BattlegroundComponent},
{ path: 'characterPicking', component: CharacterPickingComponent},
{ path: 'weaponPicking', component: WeaponPickingComponent},
{ path: '**', redirectTo: ''},

If above is my rounting path. As you can see, character picking and weapon picking are common components. If I bind the path /characterPicking to the 3 options on menu page. And bind /weaponPicking to the Next Button on characterPicking page.
Then how to bind the path for the Next Button on weaponPicking page, how to let weapon picking page know which page should it go next? Arena/Dungeon/BattleGround ?

I hope I explained this clear..

Body:
Okay, you have three buttons, but all of them navigate to the same path '/characterPicking'. I think you should manage the button click before navigate and store whitch button the user pressed.
Then the user pick his character and navigate to '/weaponPicking' and when he press the last next button you should read the option and navigate to the correct path between 'arena', 'dungeon' or 'battleground'.

Something like this i think:

@Component({
  selector: 'app-menu',
  template: `
    <button (click)="go('arena')">Arena</button>
    <button (click)="go('dungeon')">Dungeon</button>
    <button (click)="go('battlegroud')">Battleground</button>
  `,
  styles: []
})
export class MenuComponent {

  go(where){
    this.stateService.option = where;
    this.router.navigate(['characterPicking'])
  }
}

And then in your WeaponPickingComponent can do something like this:

@Component({
  selector: 'app-weapon-picking',
  template: `
    <button (click)="next()">Next</button>
  `,
  styles: []
})
export class WeaponPickingComponent {

  next(){
    switch(this.stateService.option){
      case 'arena':
        this.router.navigate(['arena']);
        break;
      case 'dungeon':
        this.router.navigate(['dungeon']);
        break;
      case 'battlegroud':
        this.router.navigate(['battleground']);
        break;
    }
  }
}


问:
Action buttons in ASP.NET Core 2.2 razor view
Suppose we're redesigning the view below:

The current code is:

```<code>@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Url)
        </td>
        <td>
            <a asp-action="Edit" asp-route-id="@item.BlogId">Edit</a> |
            <a asp-action="Details" asp-route-id="@item.BlogId">Details</a> |
            <a asp-action="Delete" asp-route-id="@item.BlogId">Delete</a>
        </td>
    </tr>
}
</code>```

Our goal is to remove the Delete view that is linked in each row. Instead we would like to have a delete button that deletes the row upon confirmation without leaving the Index page (reload is fine).

How would one go about implementing such button? And is there any relevant documentation?

答:
If you just want to remove the extra 'delete' view, you can move the delete code from the delete page tot he index page and use a simple html-form. e.g.

```<code><form method="post" asp-page-handler="Delete" class="btn-group-sm" >
    <a asp-page="./Edit" asp-route-id="@item.Id" class="btn btn-warning">Edit</a>
    <a asp-page="./Details" asp-route-id="@item.Id" class="btn btn-info">Details</a>
    <input type="hidden" asp-for="@item.Id" />
    <input type="submit" value="Delete" class="btn btn-danger" onclick="return confirm('Are you sure you wish to delete this q-Section?')" />
</form>
</code>```

Rename the 'OnPost' function to 'OnPostDelete' and it will work. You can do the same for the 'delete' button on the details page.
Regards Ken.

Body:
Suppose we're redesigning the view below:

The current code is:

@foreach (var item in Model) {

            @Html.DisplayFor(modelItem => item.Url)

            Edit |
            Details |
            Delete

}

Our goal is to remove the Delete view that is linked in each row. Instead we would like to have a delete button that deletes the row upon confirmation without leaving the Index page (reload is fine).

How would one go about implementing such button? And is there any relevant documentation?

Body:
If you just want to remove the extra 'delete' view, you can move the delete code from the delete page tot he index page and use a simple html-form. e.g.

<form method="post" asp-page-handler="Delete" class="btn-group-sm" >
    <a asp-page="./Edit" asp-route-id="@item.Id" class="btn btn-warning">Edit</a>
    <a asp-page="./Details" asp-route-id="@item.Id" class="btn btn-info">Details</a>
    <input type="hidden" asp-for="@item.Id" />
    <input type="submit" value="Delete" class="btn btn-danger" onclick="return confirm('Are you sure you wish to delete this q-Section?')" />
</form>

Rename the 'OnPost' function to 'OnPostDelete' and it will work. You can do the same for the 'delete' button on the details page.
Regards Ken.


答:
You almost have it.

This will give you the index of the last occurrence of the max value

```<code>np.where(arr == np.max(arr))[0][-1]
</code>```

and if you want the first occurence of the maximum value, it is :

```<code>np.where(arr == np.max(arr))[0][0]
</code>```

Example

```<code>import numpy as np

arr = np.array(np.random.choice([1, 2, 3, 4], size=10))
print(arr)

Output : [4 1 2 4 1 1 4 2 4 3]
</code>```

Then:

```<code>np.where(arr == np.max(arr))[0][-1] # last index of max value

Output: 8
</code>```

or

```<code>np.where(arr == np.max(arr))[0][0] # first index of max value

Output: 0
</code>```

You can then proceed to replace by index.

Title: How to set first value in numpy array that meets a condition to 1 but not the rest

Body:
You almost have it.

This will give you the index of the last occurrence of the max value

np.where(arr == np.max(arr))[0][-1]

and if you want the first occurence of the maximum value, it is :

np.where(arr == np.max(arr))[0][0]

Example

import numpy as np

arr = np.array(np.random.choice([1, 2, 3, 4], size=10))
print(arr)

Output : [4 1 2 4 1 1 4 2 4 3]

Then:

np.where(arr == np.max(arr))[0][-1] # last index of max value

Output: 8

or

np.where(arr == np.max(arr))[0][0] # first index of max value

Output: 0

You can then proceed to replace by index.


问:
Android: How to get values in under specific xml tags
I want to get values under specific tags of my xml file (accessed via url) which look like this:

```<code><SyncLoginResponse>
    <Videos>
    <Video>
        <name>27/flv</name>
        <title>scooter</title>
        <url>http://dev2.somedomain.com/tabletcms/tablets/tablet_content/000002/videos/</url>
        <thumbnail>http://dev2.somedomain.com/tabletcms/tablets/tablet_content/000002/thumbnails/106/jpg</thumbnail>

    </Video>
    <Video>
        <name>26/flv</name>
        <title>barsNtone</title>
        <url>http://dev2.somedomain.com/tabletcms/tablets/tablet_content/000002/videos/</url>
        <thumbnail>http://dev2.somedomain.com/tabletcms/tablets/tablet_content/000002/thumbnails/104/jpg</thumbnail>
    </Video>

    </Videos>
    <Slideshows>
    <Slideshow>
        <name>44</name>
        <title>ProcessFlow</title>
        <pages>4</pages>
        <url>http://dev2.somedomain.com/tabletcms/tablets/tablet_content/000002/slideshows/</url>

    </Slideshow>
    </Slideshows>
<SyncLoginResponse>
</code>```

As you can see, there are "name" tags under video while there is also "name" tag under slideshow as well as "title" and "url". I want to get the values under slideshow tag.

So far, I have the following codes:

EngagiaSync.java:

```<code>package com.example.engagiasync;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Iterator;
import java.util.List;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;

import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.widget.TextView;
public class EngagiaSync extends Activity {

    public static final int DIALOG_DOWNLOAD_PROGRESS = 0;
    private ProgressDialog mProgressDialog;
    public String FileName = "";
    public String FileURL = "";

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle icicle) {
         super.onCreate(icicle);

         /* Create a new TextView to display the parsingresult later. */
         TextView tv = new TextView(this);
         tv.setText("...PARSE AND DOWNLOAD...");

         try {
              /* Create a URL we want to load some xml-data from. */
              URL url = new URL("http://somedomain.com/tabletcms/tablets/sync_login/jayem30/jayem");
              url.openConnection();
              /* Get a SAXParser from the SAXPArserFactory. */
              SAXParserFactory spf = SAXParserFactory.newInstance();
              SAXParser sp = spf.newSAXParser();

              /* Get the XMLReader of the SAXParser we created. */
              XMLReader xr = sp.getXMLReader();
              /* Create a new ContentHandler and apply it to the XML-Reader*/
              ExampleHandler myExampleHandler = new ExampleHandler();
              xr.setContentHandler(myExampleHandler);

              /* Parse the xml-data from our URL. */
              xr.parse(new InputSource(url.openStream()));
              /* Parsing has finished. */

              /* Our ExampleHandler now provides the parsed data to us. */
              List<ParsedExampleDataSet> parsedExampleDataSet = myExampleHandler.getParsedData();

              /* Set the result to be displayed in our GUI. */
              //tv.setText(parsedExampleDataSet.toString());
              String currentFile;
              String currentFileURL;
              int x = 1;
              Iterator i;
              i = parsedExampleDataSet.iterator();
              ParsedExampleDataSet dataItem;
              while(i.hasNext()){

                   dataItem = (ParsedExampleDataSet) i.next();

                   tv.append("\nName:> " + dataItem.getName());
                   tv.append("\nTitle:> " + dataItem.getTitle());
                   tv.append("\nPages:> " + dataItem.getPages());
                   tv.append("\nFile:> " + dataItem.getUrl());

                   /*
                   int NumPages = Integer.parseInt(dataItem.getPages());

                   while( x <= NumPages ){
                       currentFile = dataItem.getName() + "-" + x + ".jpg";
                       currentFileURL = dataItem.getUrl() + currentFile;

                       tv.append("\nName: " + dataItem.getName());
                       tv.append("\nTitle: " + dataItem.getTitle());
                       tv.append("\nPages: " + NumPages );
                       tv.append("\nFile: " + currentFile);

                       startDownload(currentFile, currentFileURL);
                       x++;
                   }
                   */

              }

         } catch (Exception e) {
              /* Display any Error to the GUI. */
              tv.setText("Error: " + e.getMessage());

         }
         /* Display the TextView. */
         this.setContentView(tv);
    }

    private void startDownload(String currentFile, String currentFileURL ){
        new DownloadFileAsync().execute(currentFile, currentFileURL);
    }

    @Override
    protected Dialog onCreateDialog(int id) {
        switch (id) {
            case DIALOG_DOWNLOAD_PROGRESS:
                mProgressDialog = new ProgressDialog(this);
                mProgressDialog.setMessage("Downloading files...");
                mProgressDialog.setIndeterminate(false);
                mProgressDialog.setMax(100);
                mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
                mProgressDialog.setCancelable(true);
                mProgressDialog.show();
                return mProgressDialog;
            default:
                return null;
        }
    }

    class DownloadFileAsync extends AsyncTask<String, String, String>{

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            showDialog(DIALOG_DOWNLOAD_PROGRESS);
        }

        @Override
        protected String doInBackground(String... strings) {

            try {
                String currentFile = strings[0];
                String currentFileURL = strings[1];

                File root = Environment.getExternalStorageDirectory();
                URL u = new URL(currentFileURL);
                HttpURLConnection c = (HttpURLConnection) u.openConnection();
                c.setRequestMethod("GET");
                c.setDoOutput(true);
                c.connect();

                int lenghtOfFile = c.getContentLength();

                FileOutputStream f = new FileOutputStream(new File(root + "/download/", currentFile));

                InputStream in = c.getInputStream();

                byte[] buffer = new byte[1024];
                int len1 = 0;
                long total = 0;

                while ((len1 = in.read(buffer)) > 0) {
                    total += len1; //total = total + len1
                    publishProgress("" + (int)((total*100)/lenghtOfFile));
                    f.write(buffer, 0, len1);
                }
                f.close();
            } catch (Exception e) {
                Log.d("Downloader", e.getMessage());
            }

            return null;

        }

        protected void onProgressUpdate(String... progress) {
            Log.d("ANDRO_ASYNC",progress[0]);
            mProgressDialog.setProgress(Integer.parseInt(progress[0]));
       }

       @Override
       protected void onPostExecute(String unused) {
           dismissDialog(DIALOG_DOWNLOAD_PROGRESS);
       }

    }

}
</code>```

ExampleHandler.java:

```<code>package com.example.engagiasync;

import java.util.ArrayList;
import java.util.List;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class ExampleHandler extends DefaultHandler{

     // ===========================================================
     // Fields
     // ===========================================================

     private StringBuilder mStringBuilder = new StringBuilder();

     private ParsedExampleDataSet mParsedExampleDataSet = new ParsedExampleDataSet();
     private List<ParsedExampleDataSet> mParsedDataSetList = new ArrayList<ParsedExampleDataSet>();

     // ===========================================================
     // Getter & Setter
     // ===========================================================

     public List<ParsedExampleDataSet> getParsedData() {
          return this.mParsedDataSetList;
     }

     // ===========================================================
     // Methods
     // ===========================================================

     /** Gets be called on opening tags like:
      * <tag>
      * Can provide attribute(s), when xml was like:
      * <tag attribute="attributeValue">*/
     @Override
     public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
        if (localName.equals("Slideshow")) {
            this.mParsedExampleDataSet = new ParsedExampleDataSet();
        }

     }

     /** Gets be called on closing tags like:
      * </tag> */
     @Override
     public void endElement(String namespaceURI, String localName, String qName)
               throws SAXException {
          if (localName.equals("Slideshow")) {
               this.mParsedDataSetList.add(mParsedExampleDataSet);
          }else if (localName.equals("name")) {
               mParsedExampleDataSet.setName(mStringBuilder.toString().trim());
          }else if (localName.equals("title"))  {
              mParsedExampleDataSet.setTitle(mStringBuilder.toString().trim());
          }else if(localName.equals("pages"))  {
              mParsedExampleDataSet.setPages(mStringBuilder.toString().trim());
          }else if(localName.equals("url")){
              mParsedExampleDataSet.setUrl(mStringBuilder.toString().trim());
          }
          mStringBuilder.setLength(0);
     }

     /** Gets be called on the following structure:
      * <tag>characters</tag> */
     @Override
    public void characters(char ch[], int start, int length) {
          mStringBuilder.append(ch, start, length);
    }
}
</code>```

ParsedExampleDataSet.java:

```<code>package com.example.engagiasync;

public class ParsedExampleDataSet {
    private String name = null;
    private String title = null;
    private String pages = null;
    private String url = null;

    //name
    public String getName() {
         return name;
    }
    public void setName(String name) {
         this.name = name;
    }

    //title
    public String getTitle(){
        return title;
    }
    public void setTitle(String title){
        this.title = title;
    }

    //pages
    public String getPages(){
        return pages;
    }
    public void setPages(String pages){
        this.pages = pages;
    }

    //url
    public String getUrl(){
        return url;
    }
    public void setUrl(String url){
        this.url = url;
    }

    /*
    public String toString(){
         return "Firstname: " + this.firstname + "\n" + "Lastname: " + this.lastname + "\n" + "Address: " + this.Address + "\nFile URL: " + this.FileURL + "\n\n";
    }
    */

}
</code>```

The codes above returns the following result in the UI:

```<code>...PARSE AND DOWNLOAD...
Name:> 27/flv
Title:> scooter
Pages:> 4
File:> http://dev2.somedomain.com/tabletcms/tablets/tablet_content/000002/videos/
</code>```

In which I expect it to be:

```<code>...PARSE AND DOWNLOAD...
Name:> 44
Title:> ProcessFlow
Pages:> 4
File:> http://dev2.somedomain.com/tabletcms/tablets/tablet_content/000002/slideshows/
</code>```

答:
HI,

Keep boolean variables for the parent tags,

and do check in the EndElement() method that parent tag is true or not;

if it is true then store that particular value to corresponding variable  that is all.

e.g.

if you have

```<code><ResultSet>
<result>
<name>a</name>
</result>
<customresult>
<name>avs</customresult>
</ResultSet>
</code>```

take two variables as result & customresult of boolean type;

mark them as false initially,

check in the startElement() method whether parsing started with Result element if it so

then mark it as a true.

& now you know you are parsing result so you can easily recognize  the variable in the

result.

Best Regards,

~Anup

Body:
I want to get values under specific tags of my xml file (accessed via url) which look like this:

<SyncLoginResponse>
    <Videos>
    <Video>
        <name>27/flv</name>
        <title>scooter</title>
        <url>http://dev2.somedomain.com/tabletcms/tablets/tablet_content/000002/videos/</url>
        <thumbnail>http://dev2.somedomain.com/tabletcms/tablets/tablet_content/000002/thumbnails/106/jpg</thumbnail>

    </Video>
    <Video>
        <name>26/flv</name>
        <title>barsNtone</title>
        <url>http://dev2.somedomain.com/tabletcms/tablets/tablet_content/000002/videos/</url>
        <thumbnail>http://dev2.somedomain.com/tabletcms/tablets/tablet_content/000002/thumbnails/104/jpg</thumbnail>
    </Video>

    </Videos>
    <Slideshows>
    <Slideshow>
        <name>44</name>
        <title>ProcessFlow</title>
        <pages>4</pages>
        <url>http://dev2.somedomain.com/tabletcms/tablets/tablet_content/000002/slideshows/</url>

    </Slideshow>
    </Slideshows>
<SyncLoginResponse>

As you can see, there are "name" tags under video while there is also "name" tag under slideshow as well as "title" and "url". I want to get the values under slideshow tag.

So far, I have the following codes:

EngagiaSync.java:

package com.example.engagiasync;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Iterator;
import java.util.List;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;

import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.widget.TextView;
public class EngagiaSync extends Activity {

    public static final int DIALOG_DOWNLOAD_PROGRESS = 0;
    private ProgressDialog mProgressDialog;
    public String FileName = "";
    public String FileURL = "";

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle icicle) {
         super.onCreate(icicle);

         /* Create a new TextView to display the parsingresult later. */
         TextView tv = new TextView(this);
         tv.setText("...PARSE AND DOWNLOAD...");

         try {
              /* Create a URL we want to load some xml-data from. */
              URL url = new URL("http://somedomain.com/tabletcms/tablets/sync_login/jayem30/jayem");
              url.openConnection();
              /* Get a SAXParser from the SAXPArserFactory. */
              SAXParserFactory spf = SAXParserFactory.newInstance();
              SAXParser sp = spf.newSAXParser();

              /* Get the XMLReader of the SAXParser we created. */
              XMLReader xr = sp.getXMLReader();
              /* Create a new ContentHandler and apply it to the XML-Reader*/
              ExampleHandler myExampleHandler = new ExampleHandler();
              xr.setContentHandler(myExampleHandler);

              /* Parse the xml-data from our URL. */
              xr.parse(new InputSource(url.openStream()));
              /* Parsing has finished. */

              /* Our ExampleHandler now provides the parsed data to us. */
              List<ParsedExampleDataSet> parsedExampleDataSet = myExampleHandler.getParsedData();

              /* Set the result to be displayed in our GUI. */
              //tv.setText(parsedExampleDataSet.toString());
              String currentFile;
              String currentFileURL;
              int x = 1;
              Iterator i;
              i = parsedExampleDataSet.iterator();
              ParsedExampleDataSet dataItem;
              while(i.hasNext()){

                   dataItem = (ParsedExampleDataSet) i.next();

                   tv.append("\nName:> " + dataItem.getName());
                   tv.append("\nTitle:> " + dataItem.getTitle());
                   tv.append("\nPages:> " + dataItem.getPages());
                   tv.append("\nFile:> " + dataItem.getUrl());

                   /*
                   int NumPages = Integer.parseInt(dataItem.getPages());

                   while( x <= NumPages ){
                       currentFile = dataItem.getName() + "-" + x + ".jpg";
                       currentFileURL = dataItem.getUrl() + currentFile;

                       tv.append("\nName: " + dataItem.getName());
                       tv.append("\nTitle: " + dataItem.getTitle());
                       tv.append("\nPages: " + NumPages );
                       tv.append("\nFile: " + currentFile);

                       startDownload(currentFile, currentFileURL);
                       x++;
                   }
                   */

              }

         } catch (Exception e) {
              /* Display any Error to the GUI. */
              tv.setText("Error: " + e.getMessage());

         }
         /* Display the TextView. */
         this.setContentView(tv);
    }

    private void startDownload(String currentFile, String currentFileURL ){
        new DownloadFileAsync().execute(currentFile, currentFileURL);
    }

    @Override
    protected Dialog onCreateDialog(int id) {
        switch (id) {
            case DIALOG_DOWNLOAD_PROGRESS:
                mProgressDialog = new ProgressDialog(this);
                mProgressDialog.setMessage("Downloading files...");
                mProgressDialog.setIndeterminate(false);
                mProgressDialog.setMax(100);
                mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
                mProgressDialog.setCancelable(true);
                mProgressDialog.show();
                return mProgressDialog;
            default:
                return null;
        }
    }

    class DownloadFileAsync extends AsyncTask<String, String, String>{

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            showDialog(DIALOG_DOWNLOAD_PROGRESS);
        }

        @Override
        protected String doInBackground(String... strings) {

            try {
                String currentFile = strings[0];
                String currentFileURL = strings[1];

                File root = Environment.getExternalStorageDirectory();
                URL u = new URL(currentFileURL);
                HttpURLConnection c = (HttpURLConnection) u.openConnection();
                c.setRequestMethod("GET");
                c.setDoOutput(true);
                c.connect();

                int lenghtOfFile = c.getContentLength();

                FileOutputStream f = new FileOutputStream(new File(root + "/download/", currentFile));

                InputStream in = c.getInputStream();

                byte[] buffer = new byte[1024];
                int len1 = 0;
                long total = 0;

                while ((len1 = in.read(buffer)) > 0) {
                    total += len1; //total = total + len1
                    publishProgress("" + (int)((total*100)/lenghtOfFile));
                    f.write(buffer, 0, len1);
                }
                f.close();
            } catch (Exception e) {
                Log.d("Downloader", e.getMessage());
            }

            return null;

        }

        protected void onProgressUpdate(String... progress) {
            Log.d("ANDRO_ASYNC",progress[0]);
            mProgressDialog.setProgress(Integer.parseInt(progress[0]));
       }

       @Override
       protected void onPostExecute(String unused) {
           dismissDialog(DIALOG_DOWNLOAD_PROGRESS);
       }

    }

}

ExampleHandler.java:

package com.example.engagiasync;

import java.util.ArrayList;
import java.util.List;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class ExampleHandler extends DefaultHandler{

     // ===========================================================
     // Fields
     // ===========================================================

     private StringBuilder mStringBuilder = new StringBuilder();

     private ParsedExampleDataSet mParsedExampleDataSet = new ParsedExampleDataSet();
     private List<ParsedExampleDataSet> mParsedDataSetList = new ArrayList<ParsedExampleDataSet>();

     // ===========================================================
     // Getter & Setter
     // ===========================================================

     public List<ParsedExampleDataSet> getParsedData() {
          return this.mParsedDataSetList;
     }

     // ===========================================================
     // Methods
     // ===========================================================

     /** Gets be called on opening tags like:
      * <tag>
      * Can provide attribute(s), when xml was like:
      * <tag attribute="attributeValue">*/
     @Override
     public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
        if (localName.equals("Slideshow")) {
            this.mParsedExampleDataSet = new ParsedExampleDataSet();
        }

     }

     /** Gets be called on closing tags like:
      * </tag> */
     @Override
     public void endElement(String namespaceURI, String localName, String qName)
               throws SAXException {
          if (localName.equals("Slideshow")) {
               this.mParsedDataSetList.add(mParsedExampleDataSet);
          }else if (localName.equals("name")) {
               mParsedExampleDataSet.setName(mStringBuilder.toString().trim());
          }else if (localName.equals("title"))  {
              mParsedExampleDataSet.setTitle(mStringBuilder.toString().trim());
          }else if(localName.equals("pages"))  {
              mParsedExampleDataSet.setPages(mStringBuilder.toString().trim());
          }else if(localName.equals("url")){
              mParsedExampleDataSet.setUrl(mStringBuilder.toString().trim());
          }
          mStringBuilder.setLength(0);
     }

     /** Gets be called on the following structure:
      * <tag>characters</tag> */
     @Override
    public void characters(char ch[], int start, int length) {
          mStringBuilder.append(ch, start, length);
    }
}

ParsedExampleDataSet.java:

package com.example.engagiasync;

public class ParsedExampleDataSet {
    private String name = null;
    private String title = null;
    private String pages = null;
    private String url = null;

    //name
    public String getName() {
         return name;
    }
    public void setName(String name) {
         this.name = name;
    }

    //title
    public String getTitle(){
        return title;
    }
    public void setTitle(String title){
        this.title = title;
    }

    //pages
    public String getPages(){
        return pages;
    }
    public void setPages(String pages){
        this.pages = pages;
    }

    //url
    public String getUrl(){
        return url;
    }
    public void setUrl(String url){
        this.url = url;
    }

    /*
    public String toString(){
         return "Firstname: " + this.firstname + "\n" + "Lastname: " + this.lastname + "\n" + "Address: " + this.Address + "\nFile URL: " + this.FileURL + "\n\n";
    }
    */

}

The codes above returns the following result in the UI:

...PARSE AND DOWNLOAD...
Name:> 27/flv
Title:> scooter
Pages:> 4
File:> http://dev2.somedomain.com/tabletcms/tablets/tablet_content/000002/videos/

In which I expect it to be:

...PARSE AND DOWNLOAD...
Name:> 44
Title:> ProcessFlow
Pages:> 4
File:> http://dev2.somedomain.com/tabletcms/tablets/tablet_content/000002/slideshows/

Body:
HI,

Keep boolean variables for the parent tags,

and do check in the EndElement() method that parent tag is true or not;

if it is true then store that particular value to corresponding variable  that is all.

e.g.

if you have

<ResultSet>
<result>
<name>a</name>
</result>
<customresult>
<name>avs</customresult>
</ResultSet>

take two variables as result & customresult of boolean type;

mark them as false initially,

check in the startElement() method whether parsing started with Result element if it so

then mark it as a true.

& now you know you are parsing result so you can easily recognize  the variable in the

result.

Best Regards,

~Anup


问:
Adding a GIN index on a JSONB column slows down my request
I come from Mysql and nosql database, and I am new to Postgress db. I am using Postgres 11.6 on Aurora AWS.

I am trying to create tables made of two columns, a key and a jsonb value.

Each value looks like  this:

```<code>{"game": "game6",
   "username": "Djobi",
   (bunch of fields)
   "permissions": ["permission3", "permission1", "permission5"]}
</code>```

I am trying to add different indexes to see what are the capacities of the DB. One of them, is to find user by their name. The other is to find users having specific permission.

 account_index   | account_index_username    | CREATE INDEX account_index_username ON public.account_index USING btree (((value -> 'username'::text)))
 account_index   | account_index_permissions | CREATE INDEX account_index_permissions ON public.account_index USING gin (((value -> 'permissions'::text)))
 account_index   | account_global_gin        | CREATE INDEX accountgin ON public.account_index USING gin (value)
```

<p>I have two tables, with the exact same data. Each tables have about 30 millions rows. One with the index, one without. I am runing the following queries to test the performances:</p>

```SELECT 1
FROM account_noindex
WHERE value @> '{"permissions": ["permission1"]}' limit 10;
```

<p>I am trying here to find user having permission1. (side note, not sure yet how to ask how to have specifically permission1 versus any permission including permission1)
When runing my request on my <strong>index tables</strong>, I get a response time of 5000ms.
When runing my request on my <strong>non index tables</strong>, I get a response time of 50 ms . </p>

<p>So the non index table is 100 time faster than the index one, which I have to say confuse me.
If I try to run a explain of the two queries I get the following results:</p>

<p>Index table:</p>

<pre class="lang-none prettyprint-override"><code>Limit  (cost=430.49..468.31 rows=10 width=32)
   ->  Bitmap Heap Scan on account_index  (cost=430.49..144146.44 rows=37999 width=32)
         Recheck Cond: (value @> '{"permissions": ["permission1"]}'::jsonb)
         ->  Bitmap Index Scan on accountgin  (cost=0.00..420.99 rows=37999 width=0)
               Index Cond: (value @> '{"permissions": ["permission1"]}'::jsonb)
(5 rows)
</code>```

Non index table

Limit  (cost=0.00..1935.23 rows=10 width=4)
   ->  Seq Scan on account_noindex  (cost=0.00..7360637.42 rows=38035 width=4)
         Filter: (value @> '{"permissions": ["permission1"]}'::jsonb)
```

<p>If I try to go deeper in offset (above 100k) the difference is less obvious, but the non index table is still faster.</p>

<p>[edit]
Here the full Analyze buffers for the indexed table:</p>

```EXPLAIN (ANALYZE, BUFFERS) SELECT value->'permissions' FROM account_index WHERE value @> '{"permissions": ["permission1"]}' limit 12;
                                                                QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=430.49..475.88 rows=12 width=32) (actual time=1926.289..1926.365 rows=12 loops=1)
   Buffers: shared hit=24398
   ->  Bitmap Heap Scan on account_index  (cost=430.49..144146.44 rows=37999 width=32) (actual time=1926.287..1926.361 rows=12 loops=1)
         Recheck Cond: (value @> '{"permissions": ["permission1"]}'::jsonb)
         Rows Removed by Index Recheck: 30
         Heap Blocks: lossy=8
         Buffers: shared hit=24398
         ->  Bitmap Index Scan on accountgin  (cost=0.00..420.99 rows=37999 width=0) (actual time=1916.655..1916.656 rows=8386144 loops=1)
               Index Cond: (value @> '{"permissions": ["permission1"]}'::jsonb)
               Buffers: shared hit=24390
 Planning Time: 0.073 ms
 Execution Time: 1927.143 ms

```

So what am I missing here? Did I create my GIN index incorrectly? Or am I doing my request wrong?

Note that I have the same issue with the index on my username. When making a request to find user with a specific username without any LIMIT, I get a full table scan with or without the GIN index. When I add the BTREE index then there is no problem and no limit is needed.

答:
JSONB columns do not have useful statistics gathered on them.  That database has to make generic assumptions about how many rows it will find that meet the @>, and these are often wrong.  When deciding the absolute best way to do a LIMIT query, it is important to have more accurate statistics.  The generic assumption is that @> will match 0.1% percent of the table.  If this is grossly wrong for your case, you will likely get bad plans.

Although the difference between the plans does seem extreme.  Without seen EXPLAIN (ANALYZE, BUFFERS) it is hard to say anything specific about that.

Note that I have the same issue with the index on my username. If I just have the GIN index, I get really weird result. When I add the BTREE index then there is no problem.

I have no idea what the "weird" results might be.  You will have to provide examples.

Body:
I come from Mysql and nosql database, and I am new to Postgress db. I am using Postgres 11.6 on Aurora AWS.

I am trying to create tables made of two columns, a key and a jsonb value.

Each value looks like  this:

{"game": "game6",
   "username": "Djobi",
   (bunch of fields)
   "permissions": ["permission3", "permission1", "permission5"]}

I am trying to add different indexes to see what are the capacities of the DB. One of them, is to find user by their name. The other is to find users having specific permission.

 account_index   | account_index_username    | CREATE INDEX account_index_username ON public.account_index USING btree (((value -> 'username'::text)))
 account_index   | account_index_permissions | CREATE INDEX account_index_permissions ON public.account_index USING gin (((value -> 'permissions'::text)))
 account_index   | account_global_gin        | CREATE INDEX accountgin ON public.account_index USING gin (value)

I have two tables, with the exact same data. Each tables have about 30 millions rows. One with the index, one without. I am runing the following queries to test the performances:

SELECT 1
FROM account_noindex
WHERE value @> '{"permissions": ["permission1"]}' limit 10;

I am trying here to find user having permission1. (side note, not sure yet how to ask how to have specifically permission1 versus any permission including permission1)
When runing my request on my index tables, I get a response time of 5000ms.
When runing my request on my non index tables, I get a response time of 50 ms .

So the non index table is 100 time faster than the index one, which I have to say confuse me.
If I try to run a explain of the two queries I get the following results:

Index table:

Limit  (cost=430.49..468.31 rows=10 width=32)
   ->  Bitmap Heap Scan on account_index  (cost=430.49..144146.44 rows=37999 width=32)
         Recheck Cond: (value @> '{"permissions": ["permission1"]}'::jsonb)
         ->  Bitmap Index Scan on accountgin  (cost=0.00..420.99 rows=37999 width=0)
               Index Cond: (value @> '{"permissions": ["permission1"]}'::jsonb)
(5 rows)

Non index table

Limit  (cost=0.00..1935.23 rows=10 width=4)
   ->  Seq Scan on account_noindex  (cost=0.00..7360637.42 rows=38035 width=4)
         Filter: (value @> '{"permissions": ["permission1"]}'::jsonb)

If I try to go deeper in offset (above 100k) the difference is less obvious, but the non index table is still faster.

[edit]
Here the full Analyze buffers for the indexed table:

EXPLAIN (ANALYZE, BUFFERS) SELECT value->'permissions' FROM account_index WHERE value @> '{"permissions": ["permission1"]}' limit 12;
                                                                QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=430.49..475.88 rows=12 width=32) (actual time=1926.289..1926.365 rows=12 loops=1)
   Buffers: shared hit=24398
   ->  Bitmap Heap Scan on account_index  (cost=430.49..144146.44 rows=37999 width=32) (actual time=1926.287..1926.361 rows=12 loops=1)
         Recheck Cond: (value @> '{"permissions": ["permission1"]}'::jsonb)
         Rows Removed by Index Recheck: 30
         Heap Blocks: lossy=8
         Buffers: shared hit=24398
         ->  Bitmap Index Scan on accountgin  (cost=0.00..420.99 rows=37999 width=0) (actual time=1916.655..1916.656 rows=8386144 loops=1)
               Index Cond: (value @> '{"permissions": ["permission1"]}'::jsonb)
               Buffers: shared hit=24390
 Planning Time: 0.073 ms
 Execution Time: 1927.143 ms

So what am I missing here? Did I create my GIN index incorrectly? Or am I doing my request wrong?

Note that I have the same issue with the index on my username. When making a request to find user with a specific username without any LIMIT, I get a full table scan with or without the GIN index. When I add the BTREE index then there is no problem and no limit is needed.


问:
understanding docker container cpu usages
docker stats shows that the cpu usage to be very high. But top command out shows that 88.3% cpu is not being used. Inside the container is a java service httpthrift service.

```<code>docker stats :
CONTAINER           CPU %               MEM USAGE / LIMIT    MEM %               NET I/O             BLOCK I/O           PIDS
8a0488xxxx5        540.9%             41.99 GiB / 44 GiB   95.43%              0 B / 0 B           0 B / 35.2 MB       286
</code>```

top output :

```<code>top - 07:56:58 up 2 days, 22:29,  0 users,  load average: 2.88, 3.01, 3.05
Tasks:  13 total,   1 running,  12 sleeping,   0 stopped,   0 zombie
%Cpu(s):  8.2 us,  2.7 sy,  0.0 ni, 88.3 id,  0.0 wa,  0.0 hi,  0.9 si,  0.0 st
KiB Mem:  65959920 total, 47983628 used, 17976292 free,   357632 buffers
KiB Swap:  7999484 total,        0 used,  7999484 free.  2788868 cached Mem

PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
  8823 root      20   0 58.950g 0.041t  21080 S 540.9 66.5  16716:32 java
</code>```

How to reduce the cpu usage and bring it under 100%?

答:
According to the top man page:

When operating in Solaris mode (`I' toggled Off), a task's cpu usage will be divided by the total number of CPUs.  After issuing this command, you'll be told the new state of this toggle.

So by pressing the key I when using top in interactive mode, you will switch to the Solaris mode and the CPU usage will be divided by the total number of CPUs (or cores).

P.S.: This option is not available on all versions of top.

Body:
docker stats shows that the cpu usage to be very high. But top command out shows that 88.3% cpu is not being used. Inside the container is a java service httpthrift service.

docker stats :
CONTAINER           CPU %               MEM USAGE / LIMIT    MEM %               NET I/O             BLOCK I/O           PIDS
8a0488xxxx5        540.9%             41.99 GiB / 44 GiB   95.43%              0 B / 0 B           0 B / 35.2 MB       286

top output :

top - 07:56:58 up 2 days, 22:29,  0 users,  load average: 2.88, 3.01, 3.05
Tasks:  13 total,   1 running,  12 sleeping,   0 stopped,   0 zombie
%Cpu(s):  8.2 us,  2.7 sy,  0.0 ni, 88.3 id,  0.0 wa,  0.0 hi,  0.9 si,  0.0 st
KiB Mem:  65959920 total, 47983628 used, 17976292 free,   357632 buffers
KiB Swap:  7999484 total,        0 used,  7999484 free.  2788868 cached Mem

PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
  8823 root      20   0 58.950g 0.041t  21080 S 540.9 66.5  16716:32 java

How to reduce the cpu usage and bring it under 100%?


问:
how do I add JavaFX to a gradle build file using Kotlin DSL?
how do I add the javafx dependencies through gradle?

```<code>thufir@dur:~/NetBeansProjects/helloWorldJavaFX$
thufir@dur:~/NetBeansProjects/helloWorldJavaFX$ gradle clean

> Configure project :
e: /home/thufir/NetBeansProjects/helloWorldJavaFX/build.gradle.kts:13:7: Unresolved reference: openjfx

FAILURE: Build failed with an exception.

* Where:
Build file '/home/thufir/NetBeansProjects/helloWorldJavaFX/build.gradle.kts' line: 13

* What went wrong:
Script compilation error:

  Line 13:   org.openjfx.javafxplugin
                 ^ Unresolved reference: openjfx

1 error

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 1s
thufir@dur:~/NetBeansProjects/helloWorldJavaFX$
</code>```

the manual says:

```<code>plugins {
  id 'application'
  id 'org.openjfx.javafxplugin' version '0.0.7'
}
</code>```

my build file has:

```<code>plugins {
    // Apply the java plugin to add support for Java
    java

  org.openjfx.javafxplugin

    // Apply the application plugin to add support for building an application
    application
}
</code>```

which is generating the above error.

答:
in the plugins-section you have to put

```<code>id("org.openjfx.javafxplugin") version "0.0.8"
</code>```

instead of just org.openjfx.javafxplugin.

After that you can put a javafx-section like

```<code>javafx {
    modules("javafx.controls", "javafx.fxml")
}
</code>```

somewhere (I prefere to put it next to the dependency-section). Here you can put in any module you need.

For further configuration posibilities have a look JavaFX Gradle Plugin.

Body:
how do I add the javafx dependencies through gradle?

thufir@dur:~/NetBeansProjects/helloWorldJavaFX$
thufir@dur:~/NetBeansProjects/helloWorldJavaFX$ gradle clean

> Configure project :
e: /home/thufir/NetBeansProjects/helloWorldJavaFX/build.gradle.kts:13:7: Unresolved reference: openjfx

FAILURE: Build failed with an exception.

* Where:
Build file '/home/thufir/NetBeansProjects/helloWorldJavaFX/build.gradle.kts' line: 13

* What went wrong:
Script compilation error:

  Line 13:   org.openjfx.javafxplugin
                 ^ Unresolved reference: openjfx

1 error

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 1s
thufir@dur:~/NetBeansProjects/helloWorldJavaFX$

the manual says:

plugins {
  id 'application'
  id 'org.openjfx.javafxplugin' version '0.0.7'
}

my build file has:

plugins {
    // Apply the java plugin to add support for Java
    java

  org.openjfx.javafxplugin

    // Apply the application plugin to add support for building an application
    application
}

which is generating the above error.

Body:
in the plugins-section you have to put

id("org.openjfx.javafxplugin") version "0.0.8"

instead of just org.openjfx.javafxplugin.

After that you can put a javafx-section like

javafx {
    modules("javafx.controls", "javafx.fxml")
}

somewhere (I prefere to put it next to the dependency-section). Here you can put in any module you need.

For further configuration posibilities have a look JavaFX Gradle Plugin.


问:
MissingMethodException while calling Groovy closure inside closure
I have a groovy script which looks similar like below:

```<code>def clouser = {
    def clouserOne = { _argsA  ->
        def clouserTwo = { _argsB ->
            // Do Something with _argsA and _argsB
            println(_argsA)
            println(_argsB)
        }
    }
}
</code>```

while calling this

```<code>clouser().clouserOne("A").clouserTwo("B")
</code>```

I am getting an error

```<code>groovy.lang.MissingMethodException: No signature of method: Script1.clouserOne() is applicable for argument types: (String) values: [A]
    at Script1.run(Script1.groovy:11)
</code>```

What is the correct way to define this kind of closure inside closure? And how to call it in a proper way?

答:
After some more reading, I came across more complex closure of closure which will accepts a closure and get executed inside closure.
For example:

```<code>someClouser = {_args -> _args }

clouser = {
    clouserOne = { String _argOne ->
        clouserTwo = { String _argTwo, Closure c={any()} ->
            print "Use _argOne: ${_argOne} and _argTwo : ${_argTwo} and invoke passed clouser ${c.call()} this way"
        }
    }
}.call()
</code>```

and it can be call or use like

```<code>clouser.clouserOne("IMAGE").clouserTwo("INSIDE") {
     someClouser "Hello World"
}
</code>```

The result will be

```<code>Use _argOne: IMAGE and _argTwo : INSIDE and invoke passed clouser Hello World this way
</code>```

Body:
I have a groovy script which looks similar like below:

def clouser = {
    def clouserOne = { _argsA  ->
        def clouserTwo = { _argsB ->
            // Do Something with _argsA and _argsB
            println(_argsA)
            println(_argsB)
        }
    }
}

while calling this

clouser().clouserOne("A").clouserTwo("B")

I am getting an error

groovy.lang.MissingMethodException: No signature of method: Script1.clouserOne() is applicable for argument types: (String) values: [A]
    at Script1.run(Script1.groovy:11)

What is the correct way to define this kind of closure inside closure? And how to call it in a proper way?

Body:
After some more reading, I came across more complex closure of closure which will accepts a closure and get executed inside closure.
For example:

someClouser = {_args -> _args }

clouser = {
    clouserOne = { String _argOne ->
        clouserTwo = { String _argTwo, Closure c={any()} ->
            print "Use _argOne: ${_argOne} and _argTwo : ${_argTwo} and invoke passed clouser ${c.call()} this way"
        }
    }
}.call()

and it can be call or use like

clouser.clouserOne("IMAGE").clouserTwo("INSIDE") {
     someClouser "Hello World"
}

The result will be

Use _argOne: IMAGE and _argTwo : INSIDE and invoke passed clouser Hello World this way