问:
Android Picasso Recyclerview Image downloading slow
I have endless recyclerview that almost mimics Instagram list/feeds. Where Image is loading into full screen width Imageview. I am using Picasso to load images. Here is my code:

```<code>public class HomeAdapter extends RecyclerView.Adapter {

Context context;

private Contract contract;

List<Feed> feeds;

static final int ITEM_TYPE_HEADER = 0;

static final int ITEM_TYPE_LOAD_MORE = 1;

static final int ITEM_TYPE_DESIGN = 2;

public HomeAdapter(Context context, List<Feed> feeds) {
    this.context = context;
    this.feeds = feeds;
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    LayoutInflater inflater = LayoutInflater.from(parent.getContext());
    View row;
    if (viewType == ITEM_TYPE_HEADER) {
        row = inflater.inflate(R.layout.list_item_home_header, parent, false);
        return new HeaderHolder(row);
    } else if (viewType == ITEM_TYPE_LOAD_MORE) {
        row = inflater.inflate(R.layout.list_item_load_more, parent, false);
        return new LoadMoreHolder(row);
    } else if (viewType == ITEM_TYPE_DESIGN) {
        row = inflater.inflate(R.layout.list_item_feed_home, parent, false);
        return new DesignItemHolder(row);
    }
    return null;
}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
    Feed feed = feeds.get(position);
    if (holder instanceof HeaderHolder) {
        HeaderHolder headerHolder = (HeaderHolder) holder;
        Header header = (Header) feed;
        headerHolder.tvTitle.setText(header.getTitle());
        headerHolder.tvDescription.setText(header.getDescription());

    } else if (holder instanceof LoadMoreHolder) {
        LoadMoreHolder loadMoreHolder = (LoadMoreHolder) holder;
        LoadMore loadMore = (LoadMore) feed;
        if(loadMore.getType() == LOAD_MORE_TYPE_PROGRESS) {
            loadMoreHolder.pbLoadMore.setVisibility(View.VISIBLE);
            loadMoreHolder.rlMessageRetry.setVisibility(View.GONE);
        } else {
            loadMoreHolder.pbLoadMore.setVisibility(View.GONE);
            loadMoreHolder.rlMessageRetry.setVisibility(View.VISIBLE);
            if(StringUtils.isValid(loadMore.getTitle())) {
                loadMoreHolder.tvTitle.setText(loadMore.getTitle());
                loadMoreHolder.tvTitle.setVisibility(View.VISIBLE);
            } else
                loadMoreHolder.tvTitle.setVisibility(View.GONE);

            if(StringUtils.isValid(loadMore.getDescription())) {
                loadMoreHolder.tvDescription.setText(loadMore.getDescription());
                loadMoreHolder.tvDescription.setVisibility(View.VISIBLE);
            } else
                loadMoreHolder.tvDescription.setVisibility(View.GONE);
        }

        loadMoreHolder.btnRetry.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(contract != null)
                    contract.onRetryLoadMoreClick();
            }
        });

    } else if (holder instanceof DesignItemHolder) {
        final DesignItemHolder designItemHolder = (DesignItemHolder) holder;
        final DesignFeed designFeed = (DesignFeed) feed;
        String title = getFeedTitle(designFeed.getDesignCategory().getTitle(), designFeed.getEvent().getTitle());
        designItemHolder.tvCategory.setText(StringUtils.toUpperCaseSentence(designFeed.getDesignCategory().getTitle()));
        designItemHolder.tvDate.setText(DateTimeUtils.formatTime(designFeed.getDate()));
        designItemHolder.tvTitle.setText(StringUtils.toUpperCaseSentence(title));
        designItemHolder.tvBrand.setText(getBrandTitle(designFeed.getBrand().getTitle()));

        if(StringUtils.isValid(designFeed.getShopLink())) {
            designItemHolder.tvShop.setVisibility(View.VISIBLE);
            if(StringUtils.isValid(designFeed.getPrice())) {
                designItemHolder.tvPrice.setVisibility(View.VISIBLE);
                designItemHolder.tvPrice.setText(designFeed.getPrice() + " PKR");
            } else
                designItemHolder.tvPrice.setVisibility(View.GONE);

            designItemHolder.tvShop.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    if(contract != null)
                        contract.onOpenShopLink(designFeed.getShopLink());
                }
            });
        }
        else {
            designItemHolder.tvPrice.setVisibility(View.GONE);
            designItemHolder.tvShop.setVisibility(View.GONE);
        }

        showFeedImage(designFeed, designItemHolder.ivThumbnail, designItemHolder.progressBar);

        Picasso.get()
                .load(designFeed.getDesignCategory().getThumbnail())
                .transform(new CircleTransform())
                .placeholder(new ColorDrawable(ContextCompat.getColor(context, R.color.colorGreyLight)))
                .into(designItemHolder.ivCategory);

        designItemHolder.ivThumbnail.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(contract != null)
                    contract.onDesignFeedClick(designFeed);
            }
        });

        designItemHolder.tvCategory.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(contract != null)
                    contract.onDesignCategoryClick(designFeed.getDesignCategory());
            }
        });

        designItemHolder.ivCategory.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(contract != null)
                    contract.onDesignCategoryClick(designFeed.getDesignCategory());
            }
        });

        designItemHolder.tvTitle.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(contract != null)
                    contract.onDesignCategoryClick(designFeed.getDesignCategory());
            }
        });

        designItemHolder.tvBrand.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(contract != null)
                    contract.onBrandClick(designFeed.getBrand());
            }
        });

        designItemHolder.ibFavourite.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(contract != null)
                    contract.onFavouriteClick(designFeed);
            }
        });

        designItemHolder.ibShare.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(contract != null)
                    contract.onShareClick(designFeed);
            }
        });

        designItemHolder.ibDownload.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(contract != null)
                    contract.onDownloadClick(designFeed);
            }
        });
    }
}

private void showFeedImage(final DesignFeed designFeed, final ImageView ivThumbnail, final ProgressBar progressBar) {
    Picasso.get()
            .load(designFeed.getThumbnail())
            .placeholder(new ColorDrawable(ContextCompat.getColor(context, R.color.colorGreyLight)))
            .networkPolicy(NetworkPolicy.OFFLINE)
            .into(ivThumbnail, new Callback() {
                @Override
                public void onSuccess() {
                }

                @Override
                public void onError(Exception e) {
                    //Try again online if cache failed
                    Picasso.get()
                            .load(designFeed.getThumbnail())
                            .placeholder(new ColorDrawable(ContextCompat.getColor(context, R.color.colorGreyLight)))
                            .into(ivThumbnail, new Callback() {
                                @Override
                                public void onSuccess() {
                                }

                                @Override
                                public void onError(Exception e) {

                                }
                            });
                }
            });
}

@Override
public int getItemViewType(int position) {
    Feed feed = feeds.get(position);
    if (feed instanceof Header)
        return ITEM_TYPE_HEADER;
    else if (feed instanceof LoadMore)
        return ITEM_TYPE_LOAD_MORE;
    else if (feed instanceof DesignFeed)
        return ITEM_TYPE_DESIGN;
    else
        return super.getItemViewType(position);
}

@Override
public int getItemCount() {
    return feeds.size();
}

public void insertFeedAtStart(Feed feed) {
    feeds.add(0, feed);
    notifyDataSetChanged();
}

public void updateFeeds(ArrayList<Feed> mFeeds) {
    feeds.addAll(mFeeds);
    notifyDataSetChanged();
}

public void addLoadMoreItem(Feed loadMoreFeed) {
    feeds.add(loadMoreFeed);
    notifyItemInserted(getItemCount() - 1);
}

public void removeItem(int index) {
    feeds.remove(index);
    notifyDataSetChanged();
}

private class DesignItemHolder extends RecyclerView.ViewHolder {
    TextView tvTitle, tvCategory, tvBrand, tvDate, tvPrice, tvShop;
    ImageView ivCategory, ivThumbnail;
    ImageButton ibFavourite, ibShare, ibDownload;
    ProgressBar progressBar;

    DesignItemHolder(View itemView) {
        super(itemView);
        tvTitle = itemView.findViewById(R.id.tvTitle);
        tvCategory = itemView.findViewById(R.id.tvCategory);
        tvBrand = itemView.findViewById(R.id.tvBrand);
        tvDate = itemView.findViewById(R.id.tvDate);
        ivCategory = itemView.findViewById(R.id.ivCategory);
        ivThumbnail = itemView.findViewById(R.id.ivThumbnail);
        tvPrice = itemView.findViewById(R.id.tvPrice);
        tvShop = itemView.findViewById(R.id.tvShop);
        ibFavourite = itemView.findViewById(R.id.ibFavourite);
        ibShare = itemView.findViewById(R.id.ibShare);
        ibDownload = itemView.findViewById(R.id.ibDownload);
        progressBar = itemView.findViewById(R.id.progressBar);
    }
}

private class HeaderHolder extends RecyclerView.ViewHolder {
    TextView tvTitle, tvDescription;
    HeaderHolder(View itemView) {
        super(itemView);
        tvTitle = itemView.findViewById(R.id.tvTitle);
        tvDescription = itemView.findViewById(R.id.tvDescription);
    }
}

private class LoadMoreHolder extends RecyclerView.ViewHolder {
    ProgressBar pbLoadMore;
    RelativeLayout rlMessageRetry;
    TextView tvTitle, tvDescription;
    AppCompatButton btnRetry;

    LoadMoreHolder(View itemView) {
        super(itemView);
        pbLoadMore = itemView.findViewById(R.id.pbLoadMore);
        rlMessageRetry = itemView.findViewById(R.id.rlMessageRetry);
        tvTitle = itemView.findViewById(R.id.tvTitle);
        tvDescription = itemView.findViewById(R.id.tvDescription);
        btnRetry = itemView.findViewById(R.id.btnRetry);
    }
}

public void setContract(Contract contract) {
    this.contract = contract;
}

public interface Contract {

    void onDesignCategoryClick(DesignCategory designCategory);

    void onDesignFeedClick(DesignFeed designCategory);

    void onBrandClick(Brand brand);

    void onRetryLoadMoreClick();

    void onShopClick(String shopLink);

    void onFavouriteClick(DesignFeed designFeed);

    void onShareClick(DesignFeed designFeed);

    void onDownloadClick(DesignFeed designFeed);

    void onOpenShopLink(String shopLink);
}
</code>```

}

Average image size is 80-100 kbs. But image download time is too slow. It almost takes 3-4 seconds to download an image. On the other hand when images are loading from cache it obviously loads an image in no time. I get 15 items from server to load into recyclerview which means 15 images would be downloading in parallel. But still it is quite slow as compared to Instagram or Facebook feeds.

Can anyone guide me about the correct technique to make it as fast as possible, so that when user scrolls down the list images should be already loaded instead him waiting for image to load?

答:
Please check these answers that could be useful for you.

Load large images with Picasso and custom Transform object

How to increase speed in Picasso

How to make Picasso load images faster?

You can improve this code:

```<code>Picasso.get()
        .load(designFeed.getDesignCategory().getThumbnail())
        .transform(new CircleTransform())
        .placeholder(new ColorDrawable(ContextCompat.getColor(context, R.color.colorGreyLight)))
        .into(designItemHolder.ivCategory);
</code>```

New placeholder and transformation are created every onBindViewHolder calling. So you can create local variables for this case. Something like this..

```<code>public class HomeAdapter extends RecyclerView.Adapter {

Context context;
private final CircleTransform circleTransform;
private final ColorDrawable placeholderDrawable;

.
.
.

public HomeAdapter(Context context, List<Feed> feeds) {
    this.context = context;
    this.feeds = feeds;
    this.circleTransform = new CircleTransform();
    this.placeholderDrawable = new ColorDrawable(ContextCompat.getColor(context, R.color.colorGreyLight))
}
</code>```

Usage:

```<code>Picasso.get()
        .load(designFeed.getDesignCategory().getThumbnail())
        .transform(circleTransform)
        .placeholder(placeholderDrawable)
        .into(designItemHolder.ivCategory);
</code>```

I also would recommend you take a look on the rguzman's answer. This tweak improve performance too.

Body:
I have endless recyclerview that almost mimics Instagram list/feeds. Where Image is loading into full screen width Imageview. I am using Picasso to load images. Here is my code:

public class HomeAdapter extends RecyclerView.Adapter {

Context context;

private Contract contract;

List<Feed> feeds;

static final int ITEM_TYPE_HEADER = 0;

static final int ITEM_TYPE_LOAD_MORE = 1;

static final int ITEM_TYPE_DESIGN = 2;

public HomeAdapter(Context context, List<Feed> feeds) {
    this.context = context;
    this.feeds = feeds;
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    LayoutInflater inflater = LayoutInflater.from(parent.getContext());
    View row;
    if (viewType == ITEM_TYPE_HEADER) {
        row = inflater.inflate(R.layout.list_item_home_header, parent, false);
        return new HeaderHolder(row);
    } else if (viewType == ITEM_TYPE_LOAD_MORE) {
        row = inflater.inflate(R.layout.list_item_load_more, parent, false);
        return new LoadMoreHolder(row);
    } else if (viewType == ITEM_TYPE_DESIGN) {
        row = inflater.inflate(R.layout.list_item_feed_home, parent, false);
        return new DesignItemHolder(row);
    }
    return null;
}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
    Feed feed = feeds.get(position);
    if (holder instanceof HeaderHolder) {
        HeaderHolder headerHolder = (HeaderHolder) holder;
        Header header = (Header) feed;
        headerHolder.tvTitle.setText(header.getTitle());
        headerHolder.tvDescription.setText(header.getDescription());

    } else if (holder instanceof LoadMoreHolder) {
        LoadMoreHolder loadMoreHolder = (LoadMoreHolder) holder;
        LoadMore loadMore = (LoadMore) feed;
        if(loadMore.getType() == LOAD_MORE_TYPE_PROGRESS) {
            loadMoreHolder.pbLoadMore.setVisibility(View.VISIBLE);
            loadMoreHolder.rlMessageRetry.setVisibility(View.GONE);
        } else {
            loadMoreHolder.pbLoadMore.setVisibility(View.GONE);
            loadMoreHolder.rlMessageRetry.setVisibility(View.VISIBLE);
            if(StringUtils.isValid(loadMore.getTitle())) {
                loadMoreHolder.tvTitle.setText(loadMore.getTitle());
                loadMoreHolder.tvTitle.setVisibility(View.VISIBLE);
            } else
                loadMoreHolder.tvTitle.setVisibility(View.GONE);

            if(StringUtils.isValid(loadMore.getDescription())) {
                loadMoreHolder.tvDescription.setText(loadMore.getDescription());
                loadMoreHolder.tvDescription.setVisibility(View.VISIBLE);
            } else
                loadMoreHolder.tvDescription.setVisibility(View.GONE);
        }

        loadMoreHolder.btnRetry.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(contract != null)
                    contract.onRetryLoadMoreClick();
            }
        });

    } else if (holder instanceof DesignItemHolder) {
        final DesignItemHolder designItemHolder = (DesignItemHolder) holder;
        final DesignFeed designFeed = (DesignFeed) feed;
        String title = getFeedTitle(designFeed.getDesignCategory().getTitle(), designFeed.getEvent().getTitle());
        designItemHolder.tvCategory.setText(StringUtils.toUpperCaseSentence(designFeed.getDesignCategory().getTitle()));
        designItemHolder.tvDate.setText(DateTimeUtils.formatTime(designFeed.getDate()));
        designItemHolder.tvTitle.setText(StringUtils.toUpperCaseSentence(title));
        designItemHolder.tvBrand.setText(getBrandTitle(designFeed.getBrand().getTitle()));

        if(StringUtils.isValid(designFeed.getShopLink())) {
            designItemHolder.tvShop.setVisibility(View.VISIBLE);
            if(StringUtils.isValid(designFeed.getPrice())) {
                designItemHolder.tvPrice.setVisibility(View.VISIBLE);
                designItemHolder.tvPrice.setText(designFeed.getPrice() + " PKR");
            } else
                designItemHolder.tvPrice.setVisibility(View.GONE);

            designItemHolder.tvShop.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    if(contract != null)
                        contract.onOpenShopLink(designFeed.getShopLink());
                }
            });
        }
        else {
            designItemHolder.tvPrice.setVisibility(View.GONE);
            designItemHolder.tvShop.setVisibility(View.GONE);
        }

        showFeedImage(designFeed, designItemHolder.ivThumbnail, designItemHolder.progressBar);

        Picasso.get()
                .load(designFeed.getDesignCategory().getThumbnail())
                .transform(new CircleTransform())
                .placeholder(new ColorDrawable(ContextCompat.getColor(context, R.color.colorGreyLight)))
                .into(designItemHolder.ivCategory);

        designItemHolder.ivThumbnail.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(contract != null)
                    contract.onDesignFeedClick(designFeed);
            }
        });

        designItemHolder.tvCategory.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(contract != null)
                    contract.onDesignCategoryClick(designFeed.getDesignCategory());
            }
        });

        designItemHolder.ivCategory.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(contract != null)
                    contract.onDesignCategoryClick(designFeed.getDesignCategory());
            }
        });

        designItemHolder.tvTitle.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(contract != null)
                    contract.onDesignCategoryClick(designFeed.getDesignCategory());
            }
        });

        designItemHolder.tvBrand.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(contract != null)
                    contract.onBrandClick(designFeed.getBrand());
            }
        });

        designItemHolder.ibFavourite.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(contract != null)
                    contract.onFavouriteClick(designFeed);
            }
        });

        designItemHolder.ibShare.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(contract != null)
                    contract.onShareClick(designFeed);
            }
        });

        designItemHolder.ibDownload.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(contract != null)
                    contract.onDownloadClick(designFeed);
            }
        });
    }
}

private void showFeedImage(final DesignFeed designFeed, final ImageView ivThumbnail, final ProgressBar progressBar) {
    Picasso.get()
            .load(designFeed.getThumbnail())
            .placeholder(new ColorDrawable(ContextCompat.getColor(context, R.color.colorGreyLight)))
            .networkPolicy(NetworkPolicy.OFFLINE)
            .into(ivThumbnail, new Callback() {
                @Override
                public void onSuccess() {
                }

                @Override
                public void onError(Exception e) {
                    //Try again online if cache failed
                    Picasso.get()
                            .load(designFeed.getThumbnail())
                            .placeholder(new ColorDrawable(ContextCompat.getColor(context, R.color.colorGreyLight)))
                            .into(ivThumbnail, new Callback() {
                                @Override
                                public void onSuccess() {
                                }

                                @Override
                                public void onError(Exception e) {

                                }
                            });
                }
            });
}

@Override
public int getItemViewType(int position) {
    Feed feed = feeds.get(position);
    if (feed instanceof Header)
        return ITEM_TYPE_HEADER;
    else if (feed instanceof LoadMore)
        return ITEM_TYPE_LOAD_MORE;
    else if (feed instanceof DesignFeed)
        return ITEM_TYPE_DESIGN;
    else
        return super.getItemViewType(position);
}

@Override
public int getItemCount() {
    return feeds.size();
}

public void insertFeedAtStart(Feed feed) {
    feeds.add(0, feed);
    notifyDataSetChanged();
}

public void updateFeeds(ArrayList<Feed> mFeeds) {
    feeds.addAll(mFeeds);
    notifyDataSetChanged();
}

public void addLoadMoreItem(Feed loadMoreFeed) {
    feeds.add(loadMoreFeed);
    notifyItemInserted(getItemCount() - 1);
}

public void removeItem(int index) {
    feeds.remove(index);
    notifyDataSetChanged();
}

private class DesignItemHolder extends RecyclerView.ViewHolder {
    TextView tvTitle, tvCategory, tvBrand, tvDate, tvPrice, tvShop;
    ImageView ivCategory, ivThumbnail;
    ImageButton ibFavourite, ibShare, ibDownload;
    ProgressBar progressBar;

    DesignItemHolder(View itemView) {
        super(itemView);
        tvTitle = itemView.findViewById(R.id.tvTitle);
        tvCategory = itemView.findViewById(R.id.tvCategory);
        tvBrand = itemView.findViewById(R.id.tvBrand);
        tvDate = itemView.findViewById(R.id.tvDate);
        ivCategory = itemView.findViewById(R.id.ivCategory);
        ivThumbnail = itemView.findViewById(R.id.ivThumbnail);
        tvPrice = itemView.findViewById(R.id.tvPrice);
        tvShop = itemView.findViewById(R.id.tvShop);
        ibFavourite = itemView.findViewById(R.id.ibFavourite);
        ibShare = itemView.findViewById(R.id.ibShare);
        ibDownload = itemView.findViewById(R.id.ibDownload);
        progressBar = itemView.findViewById(R.id.progressBar);
    }
}

private class HeaderHolder extends RecyclerView.ViewHolder {
    TextView tvTitle, tvDescription;
    HeaderHolder(View itemView) {
        super(itemView);
        tvTitle = itemView.findViewById(R.id.tvTitle);
        tvDescription = itemView.findViewById(R.id.tvDescription);
    }
}

private class LoadMoreHolder extends RecyclerView.ViewHolder {
    ProgressBar pbLoadMore;
    RelativeLayout rlMessageRetry;
    TextView tvTitle, tvDescription;
    AppCompatButton btnRetry;

    LoadMoreHolder(View itemView) {
        super(itemView);
        pbLoadMore = itemView.findViewById(R.id.pbLoadMore);
        rlMessageRetry = itemView.findViewById(R.id.rlMessageRetry);
        tvTitle = itemView.findViewById(R.id.tvTitle);
        tvDescription = itemView.findViewById(R.id.tvDescription);
        btnRetry = itemView.findViewById(R.id.btnRetry);
    }
}

public void setContract(Contract contract) {
    this.contract = contract;
}

public interface Contract {

    void onDesignCategoryClick(DesignCategory designCategory);

    void onDesignFeedClick(DesignFeed designCategory);

    void onBrandClick(Brand brand);

    void onRetryLoadMoreClick();

    void onShopClick(String shopLink);

    void onFavouriteClick(DesignFeed designFeed);

    void onShareClick(DesignFeed designFeed);

    void onDownloadClick(DesignFeed designFeed);

    void onOpenShopLink(String shopLink);
}

}

Average image size is 80-100 kbs. But image download time is too slow. It almost takes 3-4 seconds to download an image. On the other hand when images are loading from cache it obviously loads an image in no time. I get 15 items from server to load into recyclerview which means 15 images would be downloading in parallel. But still it is quite slow as compared to Instagram or Facebook feeds.

Can anyone guide me about the correct technique to make it as fast as possible, so that when user scrolls down the list images should be already loaded instead him waiting for image to load?

Body:
Please check these answers that could be useful for you.

Load large images with Picasso and custom Transform object

How to increase speed in Picasso

How to make Picasso load images faster?

You can improve this code:

Picasso.get()
        .load(designFeed.getDesignCategory().getThumbnail())
        .transform(new CircleTransform())
        .placeholder(new ColorDrawable(ContextCompat.getColor(context, R.color.colorGreyLight)))
        .into(designItemHolder.ivCategory);

New placeholder and transformation are created every onBindViewHolder calling. So you can create local variables for this case. Something like this..

public class HomeAdapter extends RecyclerView.Adapter {

Context context;
private final CircleTransform circleTransform;
private final ColorDrawable placeholderDrawable;

.
.
.

public HomeAdapter(Context context, List<Feed> feeds) {
    this.context = context;
    this.feeds = feeds;
    this.circleTransform = new CircleTransform();
    this.placeholderDrawable = new ColorDrawable(ContextCompat.getColor(context, R.color.colorGreyLight))
}

Usage:

Picasso.get()
        .load(designFeed.getDesignCategory().getThumbnail())
        .transform(circleTransform)
        .placeholder(placeholderDrawable)
        .into(designItemHolder.ivCategory);

I also would recommend you take a look on the rguzman's answer. This tweak improve performance too.


来源: stackexchange

问:
List remote refs failed: java.net.ConnectException: Connection time out: github.com
I've recently starting seeing the above error with ever-increasing frequency on our build server. Nothing has changed in our TeamCity configuration during this period, so I'm guessing it might be changes at GitHub that are causing the error.

I've tried changing our VCS polling interval from 60s down to 600s in case GitHub was doing some kind of connection throttling, but there has been no affect.

Is it possible to make TeamCity less sensitive to connection timeouts?

答:
As @Pure.Krome says, you can use SSH KEYS to allow you to access the Azure TFS GIT URL, or you can modify the settings in "Alternative Credentials" by checking "Enable alternate credentials" so you can access the repository by just using a username and password.

First in Azure DevOps go to your project:

Then choose Security in the RHS menu:

Finally choose "Alternate Credentials" in the LHS menu and click the "Enable authentication alternate credentials" where you will then put in your username and password:

Please beware that this is less secure than using the SSH KEYS.

ContentLicense: CC BY-SA 3.0

ContentLicense: CC BY-SA 4.0


问:
How can I get an index of an outer list element in a list of lists?
I have a list:

```<code>mylist = [[0, [0]], [2, [1]], [3, [4]], [4, [1, 4]]]

</code>```

I want to get the index of the element of the outer list given the element.

I have tried this, but this only fetches me the outer elements of the list.

```<code>get_index = [outer for outer, inner in mylist]
</code>```

I want something like this:

```<code>Input: 2
Output: 1

Input: 4
Output: 3
</code>```

答:
You can also create a function to which you pass an Input and get the corresponding index as output</p>

```<code>def get_index(inp):
    idx = [i for i, j in enumerate(mylist) if inp==j[0]]
    return idx[0]

inp = 2
get_index(inp)
# 1

inp = 4
get_index(inp)
# 3
</code>```

Body:
I have a list:

mylist = [[0, [0]], [2, [1]], [3, [4]], [4, [1, 4]]]

I want to get the index of the element of the outer list given the element.

I have tried this, but this only fetches me the outer elements of the list.

get_index = [outer for outer, inner in mylist]

I want something like this:

Input: 2
Output: 1

Input: 4
Output: 3

Body:
You can also create a function to which you pass an Input and get the corresponding index as output

def get_index(inp):
    idx = [i for i, j in enumerate(mylist) if inp==j[0]]
    return idx[0]

inp = 2
get_index(inp)
# 1

inp = 4
get_index(inp)
# 3


问:
Java: what's the big-O time of declaring an array of size n?
What is the running time of declaring an array of size n in Java? I suppose this would depend on whether the memory is zero'ed out on garbage collection (in which case it could be O(1) ) or on initialization (in which case it'd have to be O(n) ).</p>

答:
A small none professional benchmark on JRE1.6:

```<code>public static void main(String[] args) {
    long start = System.nanoTime();
    int[] x = new int[50];
    long smallArray = System.nanoTime();
    int[] m = new int[1000000];
    long bigArray = System.nanoTime();
    System.out.println("big:" +  new Long( bigArray - smallArray));
    System.out.println("small:" +  new Long( smallArray - start));

}
</code>```

gave the following result:

```<code>big:6133612
small:6159
</code>```

so I assume O(n).
of course, it is not enough to be sure, but it's a hint.

Body:
A small none professional benchmark on JRE1.6:

public static void main(String[] args) {
    long start = System.nanoTime();
    int[] x = new int[50];
    long smallArray = System.nanoTime();
    int[] m = new int[1000000];
    long bigArray = System.nanoTime();
    System.out.println("big:" +  new Long( bigArray - smallArray));
    System.out.println("small:" +  new Long( smallArray - start));

}

gave the following result:

big:6133612
small:6159

so I assume O(n).
of course, it is not enough to be sure, but it's a hint.


问:
Angular
 color change from script
im working on a angular 6. im changing the colors of a div tag from a script after a click function i need to change it back to transparent

Here is my View when i click the inheritance first line gets background color gets changed

after clicking inheritance when i click the Method Overriding the second lines get highlighted But i need to remove the background color from first line

Html code for side bar

```<code>  <div *ngFor="let classes of classesObject ">
    <input id='{{classes}}' name='radio' type='radio'>
    <label (click)="clickClass(classes)" for='{{classes}}'>
      {{classes}}
      <div class='lil_arrow'></div>
      <div class='bar'></div>
      <div class='swanky_wrapper__content'>
        <ul *ngFor="let conceptName of concepts">
          <li (click)="getConcepts(conceptName['conceptName'],[classes])">{{conceptName["conceptName"]}}</li>
        </ul>
      </div>
    </label>
  </div>
</code>```

Html code for line display

```<code> <div *ngFor="let lines of lineList; let i= index">
    <div id="line_{{i}}" class="code" >  {{lines}}</div>
 </div>
</code>```

Typescript code for getConcept method

```<code>  for (var no in this.relatedLineNo) {
    var lines = this.relatedLineNo[no] - 1;
    document.getElementById(`line_` + lines).style.backgroundColor = "black";
    document.getElementById(`line_` + lines).style.color = "white";
    document.getElementById(`line_` + lines).style.cursor = "pointer";
    document.getElementById(`line_` + lines).setAttribute("tooltip", this.messageTip);
  }
</code>```

答:
Instead of manually looking up lines in a for loop with this:

document.getElementById(

Try a bit more Angular-ish approach:

[ngClass]="{ hilite: i === relatedLineNo }"

What happens is that inside your *ngFor loop Angular will evaluate current line index "i" with relatedLineNo and will "automatically" highlight the line.

UPDATE

If "relatedLineNo" is an array then you can use this:

```<code>[ngClass]="{ hilite: relatedLineNo.indexOf(i) !== -1 }"
</code>```

Working and updated stackblitz.

Title: Angular <div> color change from script

Body:
im working on a angular 6. im changing the colors of a div tag from a script after a click function i need to change it back to transparent

Here is my View when i click the inheritance first line gets background color gets changed

after clicking inheritance when i click the Method Overriding the second lines get highlighted But i need to remove the background color from first line

Html code for side bar

    <input id='{{classes}}' name='radio' type='radio'>

      {{classes}}

{{conceptName["conceptName"]}}

Html code for line display

  {{lines}}

Typescript code for getConcept method

  for (var no in this.relatedLineNo) {
    var lines = this.relatedLineNo[no] - 1;
    document.getElementById(`line_` + lines).style.backgroundColor = "black";
    document.getElementById(`line_` + lines).style.color = "white";
    document.getElementById(`line_` + lines).style.cursor = "pointer";
    document.getElementById(`line_` + lines).setAttribute("tooltip", this.messageTip);
  }

Body:
Instead of manually looking up lines in a for loop with this:

document.getElementById(

Try a bit more Angular-ish approach:

[ngClass]="{ hilite: i === relatedLineNo }"

What happens is that inside your *ngFor loop Angular will evaluate current line index "i" with relatedLineNo and will "automatically" highlight the line.

UPDATE

If "relatedLineNo" is an array then you can use this:

[ngClass]="{ hilite: relatedLineNo.indexOf(i) !== -1 }"

Working and updated stackblitz.


问:
Most efficient way to store unused chunk of data in PostgreSQL
There are few columns in a table and about 100+ columns based data, which only need to be stored for later export to another sources.

This data (besides the first few columns mentioned) doesn't need to be indexed / filtered or be manipulated in some sort. There are no queries, that can check this data in any way.

The only thing, that application layer can retrieve the whole row with additional unused workload and deserialize it for further conversion in external format.

There was an idea to serialize whole class into this field, but later we realized, that it's a tremendous overhead for data size (because of additional java class metadata).
So it's a simple key-value data (keys set is static as the relational model suggests).

What is a right way and data type to store this additional unused data in PostgreSQL in terms of DB performance (50+ TB storage)? Perhaps it's worth to omit key data and store only values as array (since keys are static) and get values after deserialization by index at the application layer (since DB performance on the first place)?

答:
a_horse_with_no_name, thanks a lot, but jsonb is really tricky data type.

In terms of required amount of bytes for single tuple, that contains jsonb, one must always keep in mind - the size of key names in json format.
Such that, if someone want to reinvent the wheel and store large key names as single byte indexes - it will decrease overall tuple size,
but it isn't better than storing all data as typical relational table fields, because TOAST algorithm applies for both cases.

Another way is to use EXTERNAL storage method for single jsonb field.
In that case PostgreSQL will keep more tuples in cache, since there is no need to keep whole jsonb data in memory.

Anyway, i ended up with combination of protobuf + zlib in bytea field type (since there is no need to query data in bytea field in our system) :

Uber research for protobuf + zlib


问:
Uniform generation of permutation with repetition at most k times?
We have set {1, 2, 3, ...,n} of numbers. We want to generate permutation of length of m created of those numbers with repetition of each number at most k times.

If we assume n=5, k=2, m=3, then we could receive: {3,3,1}, but not {3, 3, 3} as 3 in the second example happens to be three times in output, which is more than k.

Is there a way of uniform generation of such permutation in a fast way?

I tried two different solutions.

First:

1) generate random permutation with repetition, there is n^m different permutations.

2) check if this is a correct permutation (if it does not contain more than k times the same number

3) if yes, then return, else go to 1)

Python snippet:

```<code>import numba
import numpy as np

@numba.jit(nopython=True)
def gen_sequence1(n, k, m):
    result = np.random.randint(0, n, (1, m))[0]
    while not is_correct(result, k):
        result = np.random.randint(0, n, (1, m))[0]
    return result

@numba.jit(nopython=True)
def most_frequent(iter):
    return np.bincount(iter).max()

@numba.jit(nopython=True)
def is_correct(pruf, k):
    return most_frequent(pruf) <= k
</code>```

Second method:

Generate random integer, add it to sequence only if it didn't show up before k times. Optimized version of these words is below presented (written in Python).
Python snippet:

```<code>def gen_seq(n, d, m):
    choices = list(range(n))
    degrees = [0] * n
    result = []
    k = n - 1
    for i in range(m):
        rand = np.random.randint(0, k)
        result.append(choices[rand])
        degrees[choices[rand]] += 1
        if degrees[choices[rand]] == d:
            choices[rand], choices[k] = choices[k], choices[rand]
            k -= 1
    return result
</code>```

Problem is that the first method is very slow for n=30, m=28, d=1 it needs 10^9 times to generate sequence, which is pretty obvious.

The second one is not generating uniform permutations (some have bigger probabilities than others).

Do you have any ideas how one could generate such sequence fast and uniformly?

答:
If i remember correctly np.choice have a options to give probabilities then you can do somthing like this:

Set up the array [1..n].

Duplicate the array k times: [1..n, 1..n, 1..n, ... 1..n] into a large array.
just like @rossum proposed.

Generate probabilities for this large array uniform (1/(k*n)).

Repeat m times:

Get one number to result array

Set Probabilities that for drawned item probability will be 0 and for rest with the
same value spread between them uniformly 1/(k*n) that we just set to 0

Example:

Let S=[1,1,1,2,2,2,3,3,3,4,4,4] be a large array with k of each items inside, k=3 and m = 4.

generate P = [1/12]*len(S)

result = random(S,P) Let assume result = [1]

Probabilities  will be like this P = [0,1/12+1/36,1/12+1/36,1/12+1/36,rest remain the same]

Repeat steps 2 and 3 m times

if there is no more values that are the same as the drawn set it to 0 and make rest probabilities to keep this ration and sum to 1 . i think the hardest part will be manipulating probabilities.

Body:
We have set {1, 2, 3, ...,n} of numbers. We want to generate permutation of length of m created of those numbers with repetition of each number at most k times.

If we assume n=5, k=2, m=3, then we could receive: {3,3,1}, but not {3, 3, 3} as 3 in the second example happens to be three times in output, which is more than k.

Is there a way of uniform generation of such permutation in a fast way?

I tried two different solutions.

First:

1) generate random permutation with repetition, there is n^m different permutations.

2) check if this is a correct permutation (if it does not contain more than k times the same number

3) if yes, then return, else go to 1)

Python snippet:

import numba
import numpy as np

@numba.jit(nopython=True)
def gen_sequence1(n, k, m):
    result = np.random.randint(0, n, (1, m))[0]
    while not is_correct(result, k):
        result = np.random.randint(0, n, (1, m))[0]
    return result

@numba.jit(nopython=True)
def most_frequent(iter):
    return np.bincount(iter).max()

@numba.jit(nopython=True)
def is_correct(pruf, k):
    return most_frequent(pruf) <= k

Second method:

Generate random integer, add it to sequence only if it didn't show up before k times. Optimized version of these words is below presented (written in Python).
Python snippet:

def gen_seq(n, d, m):
    choices = list(range(n))
    degrees = [0] * n
    result = []
    k = n - 1
    for i in range(m):
        rand = np.random.randint(0, k)
        result.append(choices[rand])
        degrees[choices[rand]] += 1
        if degrees[choices[rand]] == d:
            choices[rand], choices[k] = choices[k], choices[rand]
            k -= 1
    return result

Problem is that the first method is very slow for n=30, m=28, d=1 it needs 10^9 times to generate sequence, which is pretty obvious.

The second one is not generating uniform permutations (some have bigger probabilities than others).

Do you have any ideas how one could generate such sequence fast and uniformly?


问:
How to get sorted data based on timestamp from firebase database
In my firebase database I am storing data like this

pic 2.

Now I want to retrieve and show the data in decending/latest order on my RecyclerView from firebase realtime database based on timestamp.

I have tried layoutmanager.setReverseLayout(true); and
    layoutmanager.setStackFromEnd(true); for reversing the RecyclerView but it always shows data from the middle and also I don't want to follow this method.
Since i am adding all the data into ArrayList resultsHistory. Now how can i sort the Arraylist based on latest timestamp and then setting my adapter? does it gonna solve the problem?

Below is my code:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_history);

    customerOrDriver = getIntent().getExtras().getString("customerOrDriver");
    sharedPreferences = PreferenceManager.getDefaultSharedPreferences(HistoryActivity.this);

    userId = sharedPreferences.getString("UID", "");

    mHistoryRecyclerView = (RecyclerView) findViewById(R.id.historyRecyclerView);

    //mHistoryAdapter = new HistoryAdapter(getDataSetHistory(), HistoryActivity.this);
    mHistoryLayoutManager = new LinearLayoutManager(HistoryActivity.this);
    mHistoryRecyclerView.setLayoutManager(mHistoryLayoutManager);
    mHistoryRecyclerView.setHasFixedSize(true);
    /*// sort the recycler view to descending order
    ((LinearLayoutManager) mHistoryLayoutManager).setReverseLayout(true);
    ((LinearLayoutManager) mHistoryLayoutManager).setStackFromEnd(true);*/
    mHistoryRecyclerView.setItemAnimator(new DefaultItemAnimator());
    mHistoryRecyclerView.addItemDecoration(new DividerItemDecoration(this, LinearLayoutManager.VERTICAL));
    // mHistoryRecyclerView.setAdapter(mHistoryAdapter);

    getUserHistoryIds();
}

private void getUserHistoryIds() {
    //swipeRefreshLayout.setRefreshing(true);
    DatabaseReference userHistoryDatabase = FirebaseDatabase.getInstance().getReference().child(Common.user_table).child(customerOrDriver).child(userId).child(Common.history_table);
    userHistoryDatabase.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            if (dataSnapshot.exists()) {
                for (DataSnapshot history : dataSnapshot.getChildren()) {
                    FetchRideInformation(history.getKey());
                    //swipeRefreshLayout.setRefreshing(false);
                }
                sortDate();
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            //swipeRefreshLayout.setRefreshing(false);
        }
    });
}

private void FetchRideInformation(String rideKey) {
    DatabaseReference historyDatabase = FirebaseDatabase.getInstance().getReference().child(Common.history_table).child(rideKey);
    historyDatabase.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            if (dataSnapshot.exists()) {
                String rideId = dataSnapshot.getKey();
                timestamp = 0L;
                for (DataSnapshot child : dataSnapshot.getChildren()) {
                    if (child.getKey().equals("timestamp")) {
                        timestamp = Long.valueOf(child.getValue().toString());
                    }
                }
                getRideInformation(rideId, timestamp);
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
        }
    });
}

private void getRideInformation(final String rideId, final Long timestamp) {
    DatabaseReference historyRideInfoDb = FirebaseDatabase.getInstance().getReference().child(Common.history_table).child(rideId);
    historyRideInfoDb.addListenerForSingleValueEvent(new ValueEventListener() {
        @SuppressLint("SetTextI18n")
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            if (dataSnapshot.exists()) {
                for (DataSnapshot child : dataSnapshot.getChildren()) {
                    if (child.getKey().equals("patient")) {
                        patientId = child.getValue().toString();
                        if (!patientId.equals(userId)) {
                            userDriverOrCustomer = "Doctors";
                            getUserInformation("Patients", patientId, rideId, timestamp);
                        }
                    } else if (child.getKey().equals("patient")) {
                        patientId = child.getValue().toString();
                        if (!patientId.equals(userId)) {
                            userDriverOrCustomer = "Phamacys";
                            getUserInformation("Patients", patientId, rideId, timestamp);
                        }
                    }
                    if (child.getKey().equals("doctor")) {
                        doctorId = child.getValue().toString();
                        if (!doctorId.equals(userId)) {
                            userDriverOrCustomer = "Patients";
                            getUserInformation("Doctors", doctorId, rideId, timestamp);
                        }
                    } else if (child.getKey().equals("pharmacy")) {
                        pharmacyId = child.getValue().toString();
                        if (!pharmacyId.equals(userId)) {
                            userDriverOrCustomer = "Patients";
                            getUserInformation("Pharmacys", pharmacyId, rideId, timestamp);
                        }
                    }
                }
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
        }
    });
}

private void getUserInformation(String otherUserDriverOrCustomer, String otherUserId, final String rideId, final Long timestamp) {
    DatabaseReference mOtherUserDB = FirebaseDatabase.getInstance().getReference().child(Common.user_table).child(otherUserDriverOrCustomer).child(otherUserId);
    mOtherUserDB.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            if (dataSnapshot.exists()) {
                Map<String, Object> map = (Map<String, Object>) dataSnapshot.getValue();
                if (map.get("name") != null) {
                    name = (map.get("name").toString());
                }
                if (map.get("service") == null) {
                    service = (map.get("phone").toString());
                } else if (map.get("service") != null) {
                    service = (map.get("service").toString());
                }

                HistoryObject obj = new HistoryObject(rideId, name, service, getDate(timestamp), timestamp);
                resultsHistory.add(obj);
                mHistoryAdapter.notifyDataSetChanged();
            }

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
        }
    });
}

private String getDate(Long time) {
    Calendar cal = Calendar.getInstance(Locale.getDefault());
    cal.setTimeInMillis(time * 1000);
    String date = DateFormat.format("MMMM dd yyyy, hh:mm a", cal).toString();
    return date;
}

private ArrayList<HistoryObject> resultsHistory = new ArrayList<HistoryObject>();

private ArrayList<HistoryObject> getDataSetHistory() {
    return resultsHistory;
}

@Override
public boolean onSupportNavigateUp() {
    onBackPressed();
    return true;
}

public void sortDate() {
    /*Collections.sort(resultsHistory, new Comparator<HistoryObject>() {
        DateFormat f = new SimpleDateFormat("MMMM dd yyyy, hh:mm a");
        @Override
        public int compare(HistoryObject lhs, HistoryObject rhs) {
            try {
                return f.parse(lhs.getTime()).compareTo(f.parse(rhs.getTime()));
            } catch (ParseException e) {
                throw new IllegalArgumentException(e);
            }
        }
    });*/
    Collections.sort(resultsHistory, new Comparator<HistoryObject>() {
        public int compare(HistoryObject o1, HistoryObject o2) {
            if (o1.getT() == null || o2.getT() == null)
                return 0;
            return o2.getT().compareTo(o1.getT());
        }
    });
    mHistoryAdapter = new HistoryAdapter(resultsHistory, HistoryActivity.this);
    mHistoryRecyclerView.setAdapter(mHistoryAdapter);
}
```

答:
Ref : https://firebase.google.com/docs/database/android/lists-of-data

Sort data

To retrieve sorted data, start by specifying one of the order-by methods to determine how results are ordered:

orderByChild()

Order results by the value of a specified child key or nested child path.

orderByKey()

Order results by child keys.

orderByValue()

Order results by child values.

Edit 2

If you wan't to sort arraylist u can use comparable and comparator

Example https://beginnersbook.com/2013/12/java-arraylist-of-object-sort-example-comparable-and-comparator/


问:
Vector Drawable in the circle
is there an easy way to generate Vector Drawable that is a circle with the icon inside from the existing vector drawable?

Example:

答:
Actually it's quite simple, you just need to include both paths in a single vector, so with your paths it will look like the following:

```<code><vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="24dp"
        android:height="24dp"
        android:viewportWidth="24.0"
        android:viewportHeight="24.0">

    <path
        android:fillColor="#303F9F"
        android:pathData="M12,12m-10,0a10,10 0,1 1,20 0a10,10 0,1 1,-20 0"/>

    <path
        android:fillColor="#FFFFFF"
        android:pathData="M6.62,10.79c1.44,2.83 3.76,5.14 6.59,6.59l2.2,-2.2c0.27,-0.27 0.67,-0.36 1.02,-0.24 1.12,0.37 2.33,0.57 3.57,0.57 0.55,0 1,0.45 1,1V20c0,0.55 -0.45,1 -1,1 -9.39,0 -17,-7.61 -17,-17 0,-0.55 0.45,-1 1,-1h3.5c0.55,0 1,0.45 1,1 0,1.25 0.2,2.45 0.57,3.57 0.11,0.35 0.03,0.74 -0.25,1.02l-2.2,2.2z"/>

</vector>
</code>```

The result will obviously depend on sizes of paths in relation to each other, and since scaling them without a graphical tool is a pain, DimDim's solution with a layer-list is easier to implement.

Title: Vector Drawable in the circle

Body:
Actually it's quite simple, you just need to include both paths in a single vector, so with your paths it will look like the following:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="24dp"
        android:height="24dp"
        android:viewportWidth="24.0"
        android:viewportHeight="24.0">

    <path
        android:fillColor="#303F9F"
        android:pathData="M12,12m-10,0a10,10 0,1 1,20 0a10,10 0,1 1,-20 0"/>

    <path
        android:fillColor="#FFFFFF"
        android:pathData="M6.62,10.79c1.44,2.83 3.76,5.14 6.59,6.59l2.2,-2.2c0.27,-0.27 0.67,-0.36 1.02,-0.24 1.12,0.37 2.33,0.57 3.57,0.57 0.55,0 1,0.45 1,1V20c0,0.55 -0.45,1 -1,1 -9.39,0 -17,-7.61 -17,-17 0,-0.55 0.45,-1 1,-1h3.5c0.55,0 1,0.45 1,1 0,1.25 0.2,2.45 0.57,3.57 0.11,0.35 0.03,0.74 -0.25,1.02l-2.2,2.2z"/>

</vector>

The result will obviously depend on sizes of paths in relation to each other, and since scaling them without a graphical tool is a pain, DimDim's solution with a layer-list is easier to implement.


问:
Teamcity to github List remote refs failed not authorized jgit
Using github for windows on same machine, with same credentials works fine. Can pull/clone.

However teamcity installed as a windows service on the same machine, returns the following error

```<code>List remote refs failed: org.eclipse.jgit.errors.TransportException: https://github.com/my-private-repo.git: not authorized
</code>```

答:
You can use SSH KEYS to allow you to access the Azure TFS GIT URL, or you can modify the settings in "Alternative Credentials" by checking "Enable alternate credentials" so you can access the repository by just using a username and password.

First in Azure DevOps go to your project:

Then choose Security in the RHS menu:

Finally choose "Alternate Credentials" in the LHS menu and click the "Enable authentication alternate credentials" where you will then put in your username and password:

Please beware that this is less secure than using the SSH KEYS.

Body:
Using github for windows on same machine, with same credentials works fine. Can pull/clone.

However teamcity installed as a windows service on the same machine, returns the following error

List remote refs failed: org.eclipse.jgit.errors.TransportException: https://github.com/my-private-repo.git: not authorized


问:
How do I exclude all the values outside a circle of an image using TensorFlow operations?
This is what I mean:
using the following code, I am able to let values outside a circle become 0. The code generates an all-white image and set values outside a circle be zero.

```<code>import numpy as np
import matplotlib.pyplot as plt

width = 512
all_white_img = np.zeros(shape=[width, width], dtype=np.float)
all_white_img[:] = 1
plt.imshow(all_white_img, cmap='gray', vmax=1.0, vmin=0.0)
plt.show()

[X, Y] = np.mgrid[0:width, 0:width]
xpr = X - int(width) // 2
ypr = Y - int(width) // 2
radius = width // 2
reconstruction_circle = (xpr ** 2 + ypr ** 2) <= radius ** 2 #set circle
all_white_img[~reconstruction_circle] = 0.
plt.imshow(all_white_img, cmap='gray', vmax=1.0, vmin=0.0)
plt.show()
</code>```

Output images:

How do I do the same thing using TensorFlow efficiently?

Because numpy runs on CPU and I need something able to run on GPU.

The code is just an example, I need something that works not only for circles but also any other shapes.

Thank you!

答:
The tf.where function does exactly what I want.

```<code>import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf

width = 512
sess = tf.Session()

[X, Y] = np.mgrid[0:width, 0:width]
xpr = X - int(width) // 2
ypr = Y - int(width) // 2
radius = width // 2
reconstruction_circle = (xpr ** 2 + ypr ** 2) <= radius ** 2  #set circle

all_white_img = tf.ones(shape=[width, width], dtype=tf.float32)
plt.imshow(sess.run(all_white_img), cmap='gray', vmax=1.0, vmin=0.0)
plt.show()
reconstruction_circle = tf.cast(reconstruction_circle, tf.bool)
all_white_img = tf.where(reconstruction_circle, all_white_img, tf.zeros_like(all_white_img))
plt.imshow(sess.run(all_white_img), cmap='gray', vmax=1.0, vmin=0.0)
plt.show()
</code>```

Body:
This is what I mean:
using the following code, I am able to let values outside a circle become 0. The code generates an all-white image and set values outside a circle be zero.

import numpy as np
import matplotlib.pyplot as plt

width = 512
all_white_img = np.zeros(shape=[width, width], dtype=np.float)
all_white_img[:] = 1
plt.imshow(all_white_img, cmap='gray', vmax=1.0, vmin=0.0)
plt.show()

[X, Y] = np.mgrid[0:width, 0:width]
xpr = X - int(width) // 2
ypr = Y - int(width) // 2
radius = width // 2
reconstruction_circle = (xpr ** 2 + ypr ** 2) <= radius ** 2 #set circle
all_white_img[~reconstruction_circle] = 0.
plt.imshow(all_white_img, cmap='gray', vmax=1.0, vmin=0.0)
plt.show()

Output images:

How do I do the same thing using TensorFlow efficiently?

Because numpy runs on CPU and I need something able to run on GPU.

The code is just an example, I need something that works not only for circles but also any other shapes.

Thank you!

Body:
The tf.where function does exactly what I want.

import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf

width = 512
sess = tf.Session()

[X, Y] = np.mgrid[0:width, 0:width]
xpr = X - int(width) // 2
ypr = Y - int(width) // 2
radius = width // 2
reconstruction_circle = (xpr ** 2 + ypr ** 2) <= radius ** 2  #set circle

all_white_img = tf.ones(shape=[width, width], dtype=tf.float32)
plt.imshow(sess.run(all_white_img), cmap='gray', vmax=1.0, vmin=0.0)
plt.show()
reconstruction_circle = tf.cast(reconstruction_circle, tf.bool)
all_white_img = tf.where(reconstruction_circle, all_white_img, tf.zeros_like(all_white_img))
plt.imshow(sess.run(all_white_img), cmap='gray', vmax=1.0, vmin=0.0)
plt.show()


问:
Next / Previous Post Links from Same Category
I am dealing with a very strange code for next/previous links in WP, I cannot seem to make it work ONLY in the same category.

I tried previous answers here, to no use.

<?php
  the_post_navigation( array(
'next_text' => '' . esc_html__( 'Next', 'nubia' ) . ' ' .
'' . esc_html__( 'Next post:', 'nubia' ) . '' .
'%title',
'prev_text' => '' . esc_html__( 'Previous', 'nubia' ) . '' .
'' . esc_html__( 'Previous post:', 'nubia' ) . '' .
'%title',
  ) );
?>```

I only want help to actually change the appropriate line to make it work. Thanks.

答:
THAT is the answer :)
just add this at both ends:
  'in_same_term'               => true,

<?php
  the_post_navigation( array(
    'next_text' => '' . esc_html__( 'Next', 'nubia' ) . ' ' .
    '' . esc_html__( 'Next post:', 'nubia' ) . '' .
    '%title',            'in_same_term'               => true,
    'prev_text' => '' . esc_html__( 'Previous', 'nubia' ) . '' .
    '' . esc_html__( 'Previous post:', 'nubia' ) . '' .
    '%title',            'in_same_term'               => true,
  ) );
?>```

Body:
I am dealing with a very strange code for next/previous links in WP, I cannot seem to make it work ONLY in the same category.

I tried previous answers here, to no use.

<?php
  the_post_navigation( array(
'next_text' => '' . esc_html__( 'Next', 'nubia' ) . ' ' .
'' . esc_html__( 'Next post:', 'nubia' ) . '' .
'%title',
'prev_text' => '' . esc_html__( 'Previous', 'nubia' ) . '' .
'' . esc_html__( 'Previous post:', 'nubia' ) . '' .
'%title',
  ) );
?>

I only want help to actually change the appropriate line to make it work. Thanks.

Body:
THAT is the answer :)
just add this at both ends:
  'in_same_term'               => true,

<?php
  the_post_navigation( array(
    'next_text' => '<span class="meta-nav" aria-hidden="true"><span class="pagination__text">' . esc_html__( 'Next', 'nubia' ) . '</span><span class="pagination__icon" data-icon="ei-chevron-right" data-size="s"></span></span> ' .
    '<span class="screen-reader-text">' . esc_html__( 'Next post:', 'nubia' ) . '</span>' .
    '<span class="post-title">%title</span>',            'in_same_term'               => true,
    'prev_text' => '<span class="meta-nav" aria-hidden="true"><span class="pagination__icon" data-icon="ei-chevron-left" data-size="s"></span><span class="pagination__text">' . esc_html__( 'Previous', 'nubia' ) . '</span></span>' .
    '<span class="screen-reader-text">' . esc_html__( 'Previous post:', 'nubia' ) . '</span>' .
    '<span class="post-title">%title</span>',            'in_same_term'               => true,
  ) );
?>


问:
DisplayAlert causing crash of Xamarin app
I am using a display alert for a simple yes or no dialogue but it's freezing my UI and I have no idea why.

```<code>private  async void BtnDeleteStockTake_Clicked(object sender, EventArgs e)
{

        var selectedItem = gridItems.SelectedItem as StockTakeTransArgsSage;
        var action =  await DisplayAlert("First 1", "Are you sure you wish to delete Stock Take", "Yes", "No");
        if (action)
        {
            StockTakeTransArgsSage _item = new StockTakeTransArgsSage();
           _item =database.GetSingleStockTake(selectedItem.StockTakeId).Result;
           _item.Quantity = decimal.Parse(txtQty.Text);

            int updated = await database.DeleteStockTake(_item);
            await DisplayAlert("Second 1", "Stock Take Deleted", "OK");
            await RebindData();
        }
}
</code>```

The weird thing, as well as the display alert from the first one, do not dismiss

It's causing the UI to crash out with a fatal error however if I step through my code normally without the display alert it's fine it does display the alert but then freezes.

My Delete stock function

```<code>public async Task<int> DeleteStockTake(StockTakeTransArgsSage args)
{
   return await database.DeleteAsync(args);

}
</code>```

My Get Single function.

```<code>public async Task<StockTakeTransArgsSage> GetSingleStockTake(int ID)
{
        StockTakeTransArgsSage _stocktake = new StockTakeTransArgsSage();
        _stocktake = await database.Table<StockTakeTransArgsSage>().Where(w => w.StockTakeId == ID).FirstOrDefaultAsync();
        return _stocktake;

}
</code>```

答:
In your code only those lines can cause that behavior:

```<code>       StockTakeTransArgsSage _item = new StockTakeTransArgsSage();
       _item =database.GetSingleStockTake(selectedItem.StockTakeId).Result;
       _item.Quantity = decimal.Parse(txtQty.Text);

        int updated = await database.DeleteStockTake(_item);
</code>```

Those lines cannot be executed on UI thread without freezing it for some time. That may cause the crash, you haven't provided any information of what you see in output for the crash so it is the only likely explanation.

Body:
I am using a display alert for a simple yes or no dialogue but it's freezing my UI and I have no idea why.

private  async void BtnDeleteStockTake_Clicked(object sender, EventArgs e)
{

        var selectedItem = gridItems.SelectedItem as StockTakeTransArgsSage;
        var action =  await DisplayAlert("First 1", "Are you sure you wish to delete Stock Take", "Yes", "No");
        if (action)
        {
            StockTakeTransArgsSage _item = new StockTakeTransArgsSage();
           _item =database.GetSingleStockTake(selectedItem.StockTakeId).Result;
           _item.Quantity = decimal.Parse(txtQty.Text);

            int updated = await database.DeleteStockTake(_item);
            await DisplayAlert("Second 1", "Stock Take Deleted", "OK");
            await RebindData();
        }
}

The weird thing, as well as the display alert from the first one, do not dismiss

It's causing the UI to crash out with a fatal error however if I step through my code normally without the display alert it's fine it does display the alert but then freezes.

My Delete stock function

public async Task<int> DeleteStockTake(StockTakeTransArgsSage args)
{
   return await database.DeleteAsync(args);

}

My Get Single function.

public async Task<StockTakeTransArgsSage> GetSingleStockTake(int ID)
{
        StockTakeTransArgsSage _stocktake = new StockTakeTransArgsSage();
        _stocktake = await database.Table<StockTakeTransArgsSage>().Where(w => w.StockTakeId == ID).FirstOrDefaultAsync();
        return _stocktake;

}

Body:
In your code only those lines can cause that behavior:

       StockTakeTransArgsSage _item = new StockTakeTransArgsSage();
       _item =database.GetSingleStockTake(selectedItem.StockTakeId).Result;
       _item.Quantity = decimal.Parse(txtQty.Text);

        int updated = await database.DeleteStockTake(_item);

Those lines cannot be executed on UI thread without freezing it for some time. That may cause the crash, you haven't provided any information of what you see in output for the crash so it is the only likely explanation.


问:
Space between Column's children in Flutter
I have a Column widget with two TextField widgets as children and I want to have some space between both of them.

I already tried mainAxisAlignment: MainAxisAlignment.spaceAround, but the result was not what I wanted.

答:
The same way SizedBox is used above for the purpose of code readability, you can use the Padding widget in the same manner and not have to make it a parent widget to any of the Column's children</p>

```<code>Column(
  children: <Widget>[
    FirstWidget(),
    Padding(padding: EdgeInsets.only(top: 40.0)),
    SecondWidget(),
  ]
)
</code>```

Body:
The same way SizedBox is used above for the purpose of code readability, you can use the Padding widget in the same manner and not have to make it a parent widget to any of the Column's children

Column(
  children: <Widget>[
    FirstWidget(),
    Padding(padding: EdgeInsets.only(top: 40.0)),
    SecondWidget(),
  ]
)


问:
Method returns None even if value is not none in python 3
I'm getting input at run time. If first attempt itself correct input given means I'm not getting the error. Otherwise it is showing can't unpack non-iterable error.

I can see it is sending None if recursive method called once. Even it prints value before return, but after receiving it shows None.

```<code>class Game:
    def set_val(self):
        try:
            p1=input("Enter player 1 name:")
            p2=input("Enter player 2 name:")
            goal=int(input("Enter a number to set goal:"))
            if p1 is None or p2 is None or goal is None:
                print("Please give proper input")
                self.set_val()
            else:
                print(p1,p2,goal)
                return p1,p2,goal
        except:
            print("Please give proper input")
            self.set_val()
G=Game()

p1,p2,goal=G.set_val()
print(p1,p2,goal)
</code>```

OUTPUT:

```<code>Enter player 1 name:s
Enter player 2 name:c
Enter a number to set goal:s
Please give proper input
Enter player 1 name:s
Enter player 2 name:v
Enter a number to set goal:2
s v 2
Traceback (most recent call last):
  File "D:\test.py", line 18, in <module>
    p1,p2,goal=G.set_val()
TypeError: cannot unpack non-iterable NoneType object
</code>```

I can assume it because of recursive calls, but not able to figure it out why. Please explain give a solution to get all input values without error.

答:
1) Never do a general exception to catch everything.

2) You should NOT use recursion for user input. It consumes stack for no reason. Just use a while loop. Basically recursion is not designed to keep repeating if something fails. It is designed to dive into something and eventually come back.

3) Make sure you properly space your code. This didn't cause the issue but it does make the code hard to read. You should have a space before and after operators (i.e. =) and a space after commas with multiple elements (i.e. (1, 2, 3))

That being said, when you do recursion, you need to return the recursive call:

```<code>class Game:
    def set_val(self):
        try:
            p1 = input("Enter player 1 name:")
            p2 = input("Enter player 2 name:")
            goal = int(input("Enter a number to set goal:"))
            if p1 is None or p2 is None or goal is None:
                print("Please give proper input")
                return self.set_val()
            else:
                print(p1, p2, goal)
                return p1, p2, goal
        except:
            print("Please give proper input")
            return self.set_val()
G = Game()

p1, p2, goal = G.set_val()
print(p1, p2, goal)
</code>```

Also your if can be shortened to this:

```<code>if p1 and p2 and goal:
</code>```

Body:
I'm getting input at run time. If first attempt itself correct input given means I'm not getting the error. Otherwise it is showing can't unpack non-iterable error.

I can see it is sending None if recursive method called once. Even it prints value before return, but after receiving it shows None.

class Game:
    def set_val(self):
        try:
            p1=input("Enter player 1 name:")
            p2=input("Enter player 2 name:")
            goal=int(input("Enter a number to set goal:"))
            if p1 is None or p2 is None or goal is None:
                print("Please give proper input")
                self.set_val()
            else:
                print(p1,p2,goal)
                return p1,p2,goal
        except:
            print("Please give proper input")
            self.set_val()
G=Game()

p1,p2,goal=G.set_val()
print(p1,p2,goal)

OUTPUT:

Enter player 1 name:s
Enter player 2 name:c
Enter a number to set goal:s
Please give proper input
Enter player 1 name:s
Enter player 2 name:v
Enter a number to set goal:2
s v 2
Traceback (most recent call last):
  File "D:\test.py", line 18, in <module>
    p1,p2,goal=G.set_val()
TypeError: cannot unpack non-iterable NoneType object

I can assume it because of recursive calls, but not able to figure it out why. Please explain give a solution to get all input values without error.

Body:
1) Never do a general exception to catch everything.

2) You should NOT use recursion for user input. It consumes stack for no reason. Just use a while loop. Basically recursion is not designed to keep repeating if something fails. It is designed to dive into something and eventually come back.

3) Make sure you properly space your code. This didn't cause the issue but it does make the code hard to read. You should have a space before and after operators (i.e. =) and a space after commas with multiple elements (i.e. (1, 2, 3))

That being said, when you do recursion, you need to return the recursive call:

class Game:
    def set_val(self):
        try:
            p1 = input("Enter player 1 name:")
            p2 = input("Enter player 2 name:")
            goal = int(input("Enter a number to set goal:"))
            if p1 is None or p2 is None or goal is None:
                print("Please give proper input")
                return self.set_val()
            else:
                print(p1, p2, goal)
                return p1, p2, goal
        except:
            print("Please give proper input")
            return self.set_val()
G = Game()

p1, p2, goal = G.set_val()
print(p1, p2, goal)

Also your if can be shortened to this:

if p1 and p2 and goal:


问:
Efficiency of CUDA program/device
I see that some CUDA metrics are totally confusing. According to the definition

sm_efficiency     The percentage of time at least one warp is active on a multiprocessor averaged over all multiprocessors on the GPU

warp_execution_efficiency     Ratio of the average active threads per warp to the maximum number of threads per warp supported on a multiprocessor expressed as percentage

achieved_occupancy    Ratio of the average active warps per active cycle to the maximum number of warps supported on a multiprocessor

I wonder if there is a general relation between these metrics. For example, high occupancy always imply high warp execution efficiency and so on? Otherwise, they are orthogonal and these are cases that high SM efficiency and low occupancy is possible.

The first metric is about time but the others are about number of threads and warps.
Can someone clarify that?

答:
The first and third metrics are very closely related and positively correlated. They are both about warps over time, except that the first metric applies a "> 0" operator to the number of warps. Other than that they're the same - but that operator removes the "dimension" of number of warps and just gives you an 1/Time metric instead of Warps/Time metric.

As for the second metric, that has to do with divergence of threads within a warp. While it may correlate somewhat with the third metric, that's not obviously the case. What happens among the threads in a warp is almost orthogonal to what happens to different warps.

Title: Efficiency of CUDA program/device


问:
can't access value from outside userCompletionHandler
I am working with an API (Youtube API to be more precise...) to get a title of video.

So I basically created a function to call the API and get the answer of what I'm looking for. After that I want to be able to take that result and return it in a tableCellView.

Getting the info is fine, everything works.
But when I want to take the info and return it, there is a problem.

So here is my function:

```<code>func fetchData(userCompletionHandler: @escaping (String?, Error?) -> Void){
    var yUrl = URL(string: youtubeUrlForRequest)
    let task = URLSession.shared.dataTask(with: yUrl!) { (data, yresponse, yerror) in
        do {
            if let jsonResult = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.allowFragments) as? [String : AnyObject] {

                if var items = jsonResult["items"] as? [AnyObject]? {
                    var snippetDict = items?[0]["snippet"] as! [String: AnyObject]
                    var titleVideo = snippetDict["title"] as! String
                    userCompletionHandler(titleVideo, nil)
                }
            }
        }
        catch {
            print("json error: \(error)")
        }
    }
    task.resume()

}
</code>```

So that part above is fine.

Here is how I call my function:

```<code>fetchData ( userCompletionHandler: { (ytitle, yerror) in
        //var untitre = ""

        guard let untitle = ytitle else{
            print("Ok I'm in!!!")
            //untitle = ytitle
            //print(untitle)
            return
        }
        print("OK HERE!!!!!!!!")
        print(untitle)
    })
    //var test_titre = "Le titre est: " + bontitre
    print(untitle)
    return ()
</code>```

So the print(untitle) under the print("OK HERE!!!!!!!") is fine, I do get the data I want.

But the print(untitle) over the return() won't print the same thing. It will print the value I gave to untitle when I created it above:

```<code>var untitle: String = "a"
</code>```

My goal is to be able to have return(untitle) with the title of the video where the return() is right now.

答:
I finally manage how to get the information I wanted, with the help of DispatchGroup to make sure every pieces of info were there before doing some actions.

So main difference between the code above the following one, it's the order of the actions that changed everything. So in my old code, I used to ask for a refresh of my tableView and in that refresh function, then call the Youtube API. That setup brought me into a bottleneck. So after some advices (thank you guys!) I decided to first call the API and store result in a new array. Once everything was there (with the help of DispatchGroup), I would then refresh the tableView with the data of the fresh new array.

So here is (most of) the new code of my different functions (some are linked to buttons or other stuff on the UI):

```<code>let youtubeUrl = "https://www.googleapis.com/youtube/v3/videos?part=contentDetails%2C+snippet%2C+statistics&id="
//"AKiiekaEHhI&key="
var youtubeUrlForRequest:String = ""
let dispatchGroup = DispatchGroup()
var test_title: Array<String> = []

//func

@IBAction func plus(_ sender: NSButton) {
    if urlInput.stringValue == "" {

    } else {
        if valeurEndroit.indexOfSelectedItem == -1{
            print("coucou!")
            test_text = urlInput.stringValue
            test_data.append(test_text)
            dispatchGroup.enter()
            fetchData2(lien: test_data.last!, userCompletionHandler: {data_y, user_y, error_y in
                if let user_y = user_y{
                    self.test_title.append(user_y)
                    self.dispatchGroup.leave()
                }
            })
            dispatchGroup.notify(queue: .main) {
                //print(untitle)
                print("J'ai fini la liste de titre. Voici la liste: ")
                //print(self.test_title)
                self.urlInput.stringValue = ""
                print(self.test_title)
                self.tableView.reloadData()
            }

            //tableView.reloadData()
        }else{
            if valeurEndroit.indexOfSelectedItem >= test_data.count{
                test_text = urlInput.stringValue
                test_data.append(test_text)
                dispatchGroup.enter()
                fetchData2(lien: test_data.last!, userCompletionHandler: {data_y, user_y, error_y in
                    if let user_y = user_y{
                        self.test_title.append(user_y)
                        self.dispatchGroup.leave()
                    }
                })
                dispatchGroup.notify(queue: .main) {
                    //print(untitle)
                    print("J'ai fini la liste de titre. Voici la liste: ")
                    //print(self.test_title)
                    self.urlInput.stringValue = ""
                    print(self.test_title)
                    self.tableView.reloadData()
                }
            }else{
                var y_index = (valeurEndroit.indexOfSelectedItem)
                test_text = urlInput.stringValue
                test_data.insert(test_text, at: valeurEndroit.indexOfSelectedItem)
                dispatchGroup.enter()
                fetchData2(lien: test_data[y_index], userCompletionHandler: {data_y, user_y, error_y in
                    if let user_y = user_y{
                        self.test_title.insert(user_y, at : y_index)
                        self.dispatchGroup.leave()
                    }
                })
                dispatchGroup.notify(queue: .main) {
                    //print(untitle)
                    print("J'ai fini la liste de titre. Voici la liste: ")
                    //print(self.test_title)
                    self.urlInput.stringValue = ""
                    print(self.test_title)
                    self.tableView.reloadData()
                }
            }
        }

    // fonction du bouton +
    }
}

@IBAction func nextLien(_ sender: NSButton) {
    if test_data == [] {

    } else {
    nextUrl=test_data[0]
    var monUrl = URL(string: nextUrl)
    var maRequete = URLRequest(url: monUrl!)
    view_web.load(maRequete)
    test_data.remove(at: 0)
    test_title.remove(at: 0)
    tableView.reloadData()
    //fonction du bouton pour le prochain lien
    }
}

@IBAction func openUnFichier(_ sender: NSMenuItem) {
    let fichierPanel: NSOpenPanel = NSOpenPanel()
    fichierPanel.allowsMultipleSelection = false
    fichierPanel.canChooseFiles = true
    fichierPanel.canChooseDirectories = false
    fichierPanel.allowedFileTypes = ["txt"]
    let response = fichierPanel.runModal()
    if response == NSApplication.ModalResponse.OK{
        guard let selectedURL = fichierPanel.url else{return}
        do{
            var fullDocument = try String(contentsOf: selectedURL, encoding: String.Encoding.utf8)
            var lines : [String] = fullDocument.components(separatedBy: "\n" as String)
            for line in lines {
                test_data.append(line)
                dispatchGroup.enter()
                fetchData2(lien: test_data.last!, userCompletionHandler: {data_y, user_y, error_y in
                    if let user_y = user_y{
                        self.test_title.append(user_y)
                        self.dispatchGroup.leave()
                    }
                })
                dispatchGroup.notify(queue: .main) {
                    //print(untitle)
                    print("J'ai fini la liste de titre. Voici la liste: ")
                    //print(self.test_title)
                    self.urlInput.stringValue = ""
                    print(self.test_title)
                    self.tableView.reloadData()
                }
            }
        } catch let error as NSError{
            print("Erreur!!!!!!! \(error)")
        }
        //tableView.reloadData()
    }else {

    }
}

func numberOfRows(in tableView: NSTableView) -> Int {
    return test_title.count
}

func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? {
    return (test_title[row])

}

func fetchData2(lien: String, userCompletionHandler: @escaping (String?, String?, Error?) -> Void){
    var titleLien: String = ""
    var urlToExtract_y = lien
    var videoID_y = urlToExtract_y.components(separatedBy: "=")[1]
    var youtubeUrlForRequest_y = youtubeUrl + videoID_y + "&key=" + youtubeApiKey
    print(youtubeUrlForRequest_y)
    var Url_y = URL(string: youtubeUrlForRequest_y)
    var titleVideo_y = ""
    let task_y = URLSession.shared.dataTask(with: Url_y!) { (data_y, response, error_y) in
        do {
            if let jsonResult_y = try JSONSerialization.jsonObject(with: data_y!, options: JSONSerialization.ReadingOptions.allowFragments) as? [String : AnyObject] {

                if var items_y = jsonResult_y["items"] as? [AnyObject]? {
                    var snippetDict_y = items_y?[0]["snippet"] as! [String: AnyObject]
                    var titleVideo_y = snippetDict_y["title"] as! String
                    userCompletionHandler(titleVideo_y, titleVideo_y, nil)
                }
            }
        }
        catch {
            print("json error: \(error_y)")
        }
    }
    task_y.resume()
}

//var Outlet

@IBOutlet weak var urlInput: NSTextField!

@IBOutlet weak var view_web: WKWebView!

@IBOutlet weak var tableView: NSTableView!

@IBOutlet weak var valeurEndroit: NSComboBox!
</code>```

Some parts has not been paste here because it's not important for the comprehension or it's sensitive (Youtube API Key for example).

Body:
I am working with an API (Youtube API to be more precise...) to get a title of video.

So I basically created a function to call the API and get the answer of what I'm looking for. After that I want to be able to take that result and return it in a tableCellView.

Getting the info is fine, everything works.
But when I want to take the info and return it, there is a problem.

So here is my function:

func fetchData(userCompletionHandler: @escaping (String?, Error?) -> Void){
    var yUrl = URL(string: youtubeUrlForRequest)
    let task = URLSession.shared.dataTask(with: yUrl!) { (data, yresponse, yerror) in
        do {
            if let jsonResult = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.allowFragments) as? [String : AnyObject] {

                if var items = jsonResult["items"] as? [AnyObject]? {
                    var snippetDict = items?[0]["snippet"] as! [String: AnyObject]
                    var titleVideo = snippetDict["title"] as! String
                    userCompletionHandler(titleVideo, nil)
                }
            }
        }
        catch {
            print("json error: \(error)")
        }
    }
    task.resume()

}

So that part above is fine.

Here is how I call my function:

fetchData ( userCompletionHandler: { (ytitle, yerror) in
        //var untitre = ""

        guard let untitle = ytitle else{
            print("Ok I'm in!!!")
            //untitle = ytitle
            //print(untitle)
            return
        }
        print("OK HERE!!!!!!!!")
        print(untitle)
    })
    //var test_titre = "Le titre est: " + bontitre
    print(untitle)
    return ()

So the print(untitle) under the print("OK HERE!!!!!!!") is fine, I do get the data I want.

But the print(untitle) over the return() won't print the same thing. It will print the value I gave to untitle when I created it above:

var untitle: String = "a"

My goal is to be able to have return(untitle) with the title of the video where the return() is right now.

Body:
I finally manage how to get the information I wanted, with the help of DispatchGroup to make sure every pieces of info were there before doing some actions.

So main difference between the code above the following one, it's the order of the actions that changed everything. So in my old code, I used to ask for a refresh of my tableView and in that refresh function, then call the Youtube API. That setup brought me into a bottleneck. So after some advices (thank you guys!) I decided to first call the API and store result in a new array. Once everything was there (with the help of DispatchGroup), I would then refresh the tableView with the data of the fresh new array.

So here is (most of) the new code of my different functions (some are linked to buttons or other stuff on the UI):

let youtubeUrl = "https://www.googleapis.com/youtube/v3/videos?part=contentDetails%2C+snippet%2C+statistics&id="
//"AKiiekaEHhI&key="
var youtubeUrlForRequest:String = ""
let dispatchGroup = DispatchGroup()
var test_title: Array<String> = []

//func

@IBAction func plus(_ sender: NSButton) {
    if urlInput.stringValue == "" {

    } else {
        if valeurEndroit.indexOfSelectedItem == -1{
            print("coucou!")
            test_text = urlInput.stringValue
            test_data.append(test_text)
            dispatchGroup.enter()
            fetchData2(lien: test_data.last!, userCompletionHandler: {data_y, user_y, error_y in
                if let user_y = user_y{
                    self.test_title.append(user_y)
                    self.dispatchGroup.leave()
                }
            })
            dispatchGroup.notify(queue: .main) {
                //print(untitle)
                print("J'ai fini la liste de titre. Voici la liste: ")
                //print(self.test_title)
                self.urlInput.stringValue = ""
                print(self.test_title)
                self.tableView.reloadData()
            }

            //tableView.reloadData()
        }else{
            if valeurEndroit.indexOfSelectedItem >= test_data.count{
                test_text = urlInput.stringValue
                test_data.append(test_text)
                dispatchGroup.enter()
                fetchData2(lien: test_data.last!, userCompletionHandler: {data_y, user_y, error_y in
                    if let user_y = user_y{
                        self.test_title.append(user_y)
                        self.dispatchGroup.leave()
                    }
                })
                dispatchGroup.notify(queue: .main) {
                    //print(untitle)
                    print("J'ai fini la liste de titre. Voici la liste: ")
                    //print(self.test_title)
                    self.urlInput.stringValue = ""
                    print(self.test_title)
                    self.tableView.reloadData()
                }
            }else{
                var y_index = (valeurEndroit.indexOfSelectedItem)
                test_text = urlInput.stringValue
                test_data.insert(test_text, at: valeurEndroit.indexOfSelectedItem)
                dispatchGroup.enter()
                fetchData2(lien: test_data[y_index], userCompletionHandler: {data_y, user_y, error_y in
                    if let user_y = user_y{
                        self.test_title.insert(user_y, at : y_index)
                        self.dispatchGroup.leave()
                    }
                })
                dispatchGroup.notify(queue: .main) {
                    //print(untitle)
                    print("J'ai fini la liste de titre. Voici la liste: ")
                    //print(self.test_title)
                    self.urlInput.stringValue = ""
                    print(self.test_title)
                    self.tableView.reloadData()
                }
            }
        }

    // fonction du bouton +
    }
}

@IBAction func nextLien(_ sender: NSButton) {
    if test_data == [] {

    } else {
    nextUrl=test_data[0]
    var monUrl = URL(string: nextUrl)
    var maRequete = URLRequest(url: monUrl!)
    view_web.load(maRequete)
    test_data.remove(at: 0)
    test_title.remove(at: 0)
    tableView.reloadData()
    //fonction du bouton pour le prochain lien
    }
}

@IBAction func openUnFichier(_ sender: NSMenuItem) {
    let fichierPanel: NSOpenPanel = NSOpenPanel()
    fichierPanel.allowsMultipleSelection = false
    fichierPanel.canChooseFiles = true
    fichierPanel.canChooseDirectories = false
    fichierPanel.allowedFileTypes = ["txt"]
    let response = fichierPanel.runModal()
    if response == NSApplication.ModalResponse.OK{
        guard let selectedURL = fichierPanel.url else{return}
        do{
            var fullDocument = try String(contentsOf: selectedURL, encoding: String.Encoding.utf8)
            var lines : [String] = fullDocument.components(separatedBy: "\n" as String)
            for line in lines {
                test_data.append(line)
                dispatchGroup.enter()
                fetchData2(lien: test_data.last!, userCompletionHandler: {data_y, user_y, error_y in
                    if let user_y = user_y{
                        self.test_title.append(user_y)
                        self.dispatchGroup.leave()
                    }
                })
                dispatchGroup.notify(queue: .main) {
                    //print(untitle)
                    print("J'ai fini la liste de titre. Voici la liste: ")
                    //print(self.test_title)
                    self.urlInput.stringValue = ""
                    print(self.test_title)
                    self.tableView.reloadData()
                }
            }
        } catch let error as NSError{
            print("Erreur!!!!!!! \(error)")
        }
        //tableView.reloadData()
    }else {

    }
}

func numberOfRows(in tableView: NSTableView) -> Int {
    return test_title.count
}

func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? {
    return (test_title[row])

}

func fetchData2(lien: String, userCompletionHandler: @escaping (String?, String?, Error?) -> Void){
    var titleLien: String = ""
    var urlToExtract_y = lien
    var videoID_y = urlToExtract_y.components(separatedBy: "=")[1]
    var youtubeUrlForRequest_y = youtubeUrl + videoID_y + "&key=" + youtubeApiKey
    print(youtubeUrlForRequest_y)
    var Url_y = URL(string: youtubeUrlForRequest_y)
    var titleVideo_y = ""
    let task_y = URLSession.shared.dataTask(with: Url_y!) { (data_y, response, error_y) in
        do {
            if let jsonResult_y = try JSONSerialization.jsonObject(with: data_y!, options: JSONSerialization.ReadingOptions.allowFragments) as? [String : AnyObject] {

                if var items_y = jsonResult_y["items"] as? [AnyObject]? {
                    var snippetDict_y = items_y?[0]["snippet"] as! [String: AnyObject]
                    var titleVideo_y = snippetDict_y["title"] as! String
                    userCompletionHandler(titleVideo_y, titleVideo_y, nil)
                }
            }
        }
        catch {
            print("json error: \(error_y)")
        }
    }
    task_y.resume()
}

//var Outlet

@IBOutlet weak var urlInput: NSTextField!

@IBOutlet weak var view_web: WKWebView!

@IBOutlet weak var tableView: NSTableView!

@IBOutlet weak var valeurEndroit: NSComboBox!

Some parts has not been paste here because it's not important for the comprehension or it's sensitive (Youtube API Key for example).


问:
laravel 5.8 Auth/RegisterController custom redirect on validation failure
I'm using Laravel 5.8, I have a single page that has both the Registration and Login forms (2 separate forms posting to the respective endpoints/controllers)

My Registration Form posts to the Auth/RegistrationController as provided by Lavarel Auth.

I would like to change the behaviour so that on an unsuccessful registration attempt it will add an additional parameter to redirect url so I know which form to apply to validation feedback too.

I'm already aware of the redirectTo variable this appears to be for successful requests though

答:
You need to override the Auth/RegistrationController::register method, take a look at the default code provided by the framework and adjust it to your needs something like this:

```<code>public function register(Request $request) {

    if ($this->validator($request->all())->fails()) {
        return redirect('/foo?bar=1');
    }

    // Copy the default behaviour here
    ...
    // or you can just
    return parent::register($request);
}
</code>```

Body:
You need to override the Auth/RegistrationController::register method, take a look at the default code provided by the framework and adjust it to your needs something like this:

public function register(Request $request) {

    if ($this->validator($request->all())->fails()) {
        return redirect('/foo?bar=1');
    }

    // Copy the default behaviour here
    ...
    // or you can just
    return parent::register($request);
}


问:
JQuery select a variable by passing a text string of its name
I'd like to use a JQuery selector to return a variable by passing a text string of the variable name:

ex.

```<code>var test = "xxx";
</code>```

I'm thinking I could do something like this, but it won't work:

```<code>  alert($("#test"));
</code>```

Edit:  People are getting confused.  Think of it as a reflective way to get the contents of var test.  Preferrably with a JQuery selector, but I'll take any way one can come up with it..

答:
Not sure what your end target is, but I use the following method a lot when I need one thing to interact with another...

```<code><a href='whatever.html' rel='#targetElem' class='loadable'>
<script>
$(document).ready(function(){
  $('.loadable').live('click',function(){  //when a element with the class of loadable is clicked
    $($(this).attr('rel')).load($(this).attr('href')); //load the contents of it's href URL into the element specified in it's rel attribute
    return(false); // stop processing the link;
 });
});

</script>
</code>```

I tell the element what the target of the action will be using the rel attribute...

to get at variables try this  (window is a javascript built-in array of global variables...)

```<code>var i=2;

var test='i';
document.write('got ' + window[test]);
</code>```

Body:
I'd like to use a JQuery selector to return a variable by passing a text string of the variable name:

ex.

var test = "xxx";

I'm thinking I could do something like this, but it won't work:

  alert($("#test"));

Edit:  People are getting confused.  Think of it as a reflective way to get the contents of var test.  Preferrably with a JQuery selector, but I'll take any way one can come up with it..

Body:
Not sure what your end target is, but I use the following method a lot when I need one thing to interact with another...

<a href='whatever.html' rel='#targetElem' class='loadable'>
<script>
$(document).ready(function(){
  $('.loadable').live('click',function(){  //when a element with the class of loadable is clicked
    $($(this).attr('rel')).load($(this).attr('href')); //load the contents of it's href URL into the element specified in it's rel attribute
    return(false); // stop processing the link;
 });
});

</script>

I tell the element what the target of the action will be using the rel attribute...

to get at variables try this  (window is a javascript built-in array of global variables...)

var i=2;

var test='i';
document.write('got ' + window[test]);