问:
jQuery pagination plugin
hi could you help me with jquery pagination plugin. I wanna hide pagination panel (prev, curent, next buttons) when items on the page is too few to showed up the next page, I mean when items are only for first page.

this id from - https://github.com/gbirke/jquery_pagination

JS CODE

```<code> (function($){
    /**
     * @class Class for calculating pagination values
     */
    $.PaginationCalculator = function(maxentries, opts) {
        this.maxentries = maxentries;
        this.opts = opts;
    }

    $.extend($.PaginationCalculator.prototype, {
        /**
         * Calculate the maximum number of pages
         * @method
         * @returns {Number}
         */
        numPages:function() {
            return Math.ceil(this.maxentries/this.opts.items_per_page);
        },
        /**
         * Calculate start and end point of pagination links depending on
         * current_page and num_display_entries.
         * @returns {Array}
         */
        getInterval:function(current_page)  {
            var ne_half = Math.floor(this.opts.num_display_entries/2);
            var np = this.numPages();
            var upper_limit = np - this.opts.num_display_entries;
            var start = current_page > ne_half ? Math.max( Math.min(current_page - ne_half, upper_limit), 0 ) : 0;
            var end = current_page > ne_half?Math.min(current_page+ne_half + (this.opts.num_display_entries % 2), np):Math.min(this.opts.num_display_entries, np);
            return {start:start, end:end};
        }
    });

    // Initialize jQuery object container for pagination renderers
    $.PaginationRenderers = {}

    /**
     * @class Default renderer for rendering pagination links
     */
    $.PaginationRenderers.defaultRenderer = function(maxentries, opts) {
        this.maxentries = maxentries;
        this.opts = opts;
        this.pc = new $.PaginationCalculator(maxentries, opts);
    }
    $.extend($.PaginationRenderers.defaultRenderer.prototype, {
        /**
         * Helper function for generating a single link (or a span tag if it's the current page)
         * @param {Number} page_id The page id for the new item
         * @param {Number} current_page
         * @param {Object} appendopts Options for the new item: text and classes
         * @returns {jQuery} jQuery object containing the link
         */
        createLink:function(page_id, current_page, appendopts){
            var lnk, np = this.pc.numPages();
            page_id = page_id<0?0:(page_id<np?page_id:np-1); // Normalize page id to sane value
            appendopts = $.extend({text:page_id+1, classes:""}, appendopts||{});
            if(page_id == current_page){
                lnk = $("<span class='current'>" + appendopts.text + "</span>");

            }
            else
            {
                lnk = $("<a>" + appendopts.text + "</a>")
                    .attr('href', this.opts.link_to.replace(/__id__/,page_id));

            }
            if(appendopts.classes){ lnk.addClass(appendopts.classes); }
            lnk.data('page_id', page_id);
            return lnk;
        },
        // Generate a range of numeric links
        appendRange:function(container, current_page, start, end, opts) {
            var i;
            for(i=start; i<end; i++) {
                this.createLink(i, current_page, opts).appendTo(container);
            }
        },
        getLinks:function(current_page, eventHandler) {
            var begin, end,
                interval = this.pc.getInterval(current_page),
                np = this.pc.numPages(),
                fragment = $("<div class='pagination'></div>");

            // Generate "Previous"-Link
            if(this.opts.prev_text && (current_page > 0 || this.opts.prev_show_always)){
                fragment.append(this.createLink(current_page-1, current_page, {text:this.opts.prev_text, classes:"prev"}));
            }
            // Generate starting points
            if (interval.start > 0 && this.opts.num_edge_entries > 0)
            {
                end = Math.min(this.opts.num_edge_entries, interval.start);
                this.appendRange(fragment, current_page, 0, end, {classes:'sp'});
                if(this.opts.num_edge_entries < interval.start && this.opts.ellipse_text)
                {
                    jQuery("<span>"+this.opts.ellipse_text+"</span>").appendTo(fragment);
                }
            }
            // Generate interval links
            this.appendRange(fragment, current_page, interval.start, interval.end);
            // Generate ending points
            if (interval.end < np && this.opts.num_edge_entries > 0)
            {
                if(np-this.opts.num_edge_entries > interval.end && this.opts.ellipse_text)
                {
                    jQuery("<span>"+this.opts.ellipse_text+"</span>").appendTo(fragment);
                }
                begin = Math.max(np-this.opts.num_edge_entries, interval.end);
                this.appendRange(fragment, current_page, begin, np, {classes:'ep'});

            }
            // Generate "Next"-Link
            if(this.opts.next_text && (current_page < np-1 || this.opts.next_show_always)){
                fragment.append(this.createLink(current_page+1, current_page, {text:this.opts.next_text, classes:"next"}));
            }
            $('a', fragment).click(eventHandler);
            return fragment;
        }
    });

    // Extend jQuery
    $.fn.pagination = function(maxentries, opts){

        // Initialize options with default values
        opts = jQuery.extend({
            items_per_page:10,
            num_display_entries:11,
            current_page:0,
            num_edge_entries:0,
            link_to:"#",
            prev_text:"Prev",
            next_text:"Next",
            ellipse_text:"...",
            prev_show_always:true,
            next_show_always:true,
            renderer:"defaultRenderer",
            callback:function(){return false;}
        },opts||{});

        var containers = this,
            renderer, links, current_page;

        /**
         * This is the event handling function for the pagination links.
         * @param {int} page_id The new page number
         */
        function paginationClickHandler(evt){
            var links,
                new_current_page = $(evt.target).data('page_id'),
                continuePropagation = selectPage(new_current_page);
            if (!continuePropagation) {
                evt.stopPropagation();
            }
            return continuePropagation;
        }

        /**
         * This is a utility function for the internal event handlers.
         * It sets the new current page on the pagination container objects,
         * generates a new HTMl fragment for the pagination links and calls
         * the callback function.
         */
        function selectPage(new_current_page) {
            // update the link display of a all containers
            containers.data('current_page', new_current_page);
            links = renderer.getLinks(new_current_page, paginationClickHandler);
            containers.empty();
            links.appendTo(containers);
            // call the callback and propagate the event if it does not return false
            var continuePropagation = opts.callback(new_current_page, containers);
            return continuePropagation;
        }

        // -----------------------------------
        // Initialize containers
        // -----------------------------------
        current_page = opts.current_page;
        containers.data('current_page', current_page);
        // Create a sane value for maxentries and items_per_page
        maxentries = (!maxentries || maxentries < 0)?1:maxentries;
        opts.items_per_page = (!opts.items_per_page || opts.items_per_page < 0)?1:opts.items_per_page;

        if(!$.PaginationRenderers[opts.renderer])
        {
            throw new ReferenceError("Pagination renderer '" + opts.renderer + "' was not found in jQuery.PaginationRenderers object.");
        }
        renderer = new $.PaginationRenderers[opts.renderer](maxentries, opts);

        // Attach control events to the DOM elements
        var pc = new $.PaginationCalculator(maxentries, opts);
        var np = pc.numPages();
        containers.bind('setPage', {numPages:np}, function(evt, page_id) {
                if(page_id >= 0 && page_id < evt.data.numPages) {
                    selectPage(page_id); return false;
                }
        });
        containers.bind('prevPage', function(evt){
                var current_page = $(this).data('current_page');
                if (current_page > 0) {
                    selectPage(current_page - 1);
                }
                return false;
        });
        containers.bind('nextPage', {numPages:np}, function(evt){
                var current_page = $(this).data('current_page');
                if(current_page < evt.data.numPages - 1) {
                    selectPage(current_page + 1);
                }
                return false;
        });

        // When all initialisation is done, draw the links
        links = renderer.getLinks(current_page, paginationClickHandler);
        containers.empty();
        links.appendTo(containers);
        // call callback function
        opts.callback(current_page, containers);
    } // End of $.fn.pagination block

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

Could oyu help me with that

答:
https://github.com/gbirke/jquery_pagination

Available Options

next_show_always

If this is set to false, the "Next"-link is only shown when the page number can be increased. Default: true

prev_show_always

If this is set to false, the "Previous"-link is only shown when the page number can be decreased. Default: true

num_display_entries

Maximum number of pagination links that are visible. Set to 0 to display a simple "Previous/Next"-Navigation. Set to an odd number for maximum symmetry and aesthetic pleasure. Default: 11

```<code>if (content.length<perPage){
//pass those options to the class
}
</code>```

EDIT and since apparantly giving the solution isn't enough, I've put the all the code neatly together for you to just copy&paste now:

Less than number of items per page:
http://jsfiddle.net/niklasvh/EQVBv/

More than number of items per page:
http://jsfiddle.net/niklasvh/EQVBv/20/

Title: jQuery pagination plugin

Body:
hi could you help me with jquery pagination plugin. I wanna hide pagination panel (prev, curent, next buttons) when items on the page is too few to showed up the next page, I mean when items are only for first page.

this id from - https://github.com/gbirke/jquery_pagination

JS CODE

 (function($){
    /**
     * @class Class for calculating pagination values
     */
    $.PaginationCalculator = function(maxentries, opts) {
        this.maxentries = maxentries;
        this.opts = opts;
    }

    $.extend($.PaginationCalculator.prototype, {
        /**
         * Calculate the maximum number of pages
         * @method
         * @returns {Number}
         */
        numPages:function() {
            return Math.ceil(this.maxentries/this.opts.items_per_page);
        },
        /**
         * Calculate start and end point of pagination links depending on
         * current_page and num_display_entries.
         * @returns {Array}
         */
        getInterval:function(current_page)  {
            var ne_half = Math.floor(this.opts.num_display_entries/2);
            var np = this.numPages();
            var upper_limit = np - this.opts.num_display_entries;
            var start = current_page > ne_half ? Math.max( Math.min(current_page - ne_half, upper_limit), 0 ) : 0;
            var end = current_page > ne_half?Math.min(current_page+ne_half + (this.opts.num_display_entries % 2), np):Math.min(this.opts.num_display_entries, np);
            return {start:start, end:end};
        }
    });

    // Initialize jQuery object container for pagination renderers
    $.PaginationRenderers = {}

    /**
     * @class Default renderer for rendering pagination links
     */
    $.PaginationRenderers.defaultRenderer = function(maxentries, opts) {
        this.maxentries = maxentries;
        this.opts = opts;
        this.pc = new $.PaginationCalculator(maxentries, opts);
    }
    $.extend($.PaginationRenderers.defaultRenderer.prototype, {
        /**
         * Helper function for generating a single link (or a span tag if it's the current page)
         * @param {Number} page_id The page id for the new item
         * @param {Number} current_page
         * @param {Object} appendopts Options for the new item: text and classes
         * @returns {jQuery} jQuery object containing the link
         */
        createLink:function(page_id, current_page, appendopts){
            var lnk, np = this.pc.numPages();
            page_id = page_id<0?0:(page_id<np?page_id:np-1); // Normalize page id to sane value
            appendopts = $.extend({text:page_id+1, classes:""}, appendopts||{});
            if(page_id == current_page){
                lnk = $("" + appendopts.text + "");

            }
            else
            {
                lnk = $("" + appendopts.text + "")
                    .attr('href', this.opts.link_to.replace(/__id__/,page_id));

            }
            if(appendopts.classes){ lnk.addClass(appendopts.classes); }
            lnk.data('page_id', page_id);
            return lnk;
        },
        // Generate a range of numeric links
        appendRange:function(container, current_page, start, end, opts) {
            var i;
            for(i=start; i<end; i++) {
                this.createLink(i, current_page, opts).appendTo(container);
            }
        },
        getLinks:function(current_page, eventHandler) {
            var begin, end,
                interval = this.pc.getInterval(current_page),
                np = this.pc.numPages(),
                fragment = $("

");

            // Generate "Previous"-Link
            if(this.opts.prev_text && (current_page > 0 || this.opts.prev_show_always)){
                fragment.append(this.createLink(current_page-1, current_page, {text:this.opts.prev_text, classes:"prev"}));
            }
            // Generate starting points
            if (interval.start > 0 && this.opts.num_edge_entries > 0)
            {
                end = Math.min(this.opts.num_edge_entries, interval.start);
                this.appendRange(fragment, current_page, 0, end, {classes:'sp'});
                if(this.opts.num_edge_entries < interval.start && this.opts.ellipse_text)
                {
                    jQuery(""+this.opts.ellipse_text+"").appendTo(fragment);
                }
            }
            // Generate interval links
            this.appendRange(fragment, current_page, interval.start, interval.end);
            // Generate ending points
            if (interval.end < np && this.opts.num_edge_entries > 0)
            {
                if(np-this.opts.num_edge_entries > interval.end && this.opts.ellipse_text)
                {
                    jQuery(""+this.opts.ellipse_text+"").appendTo(fragment);
                }
                begin = Math.max(np-this.opts.num_edge_entries, interval.end);
                this.appendRange(fragment, current_page, begin, np, {classes:'ep'});

            }
            // Generate "Next"-Link
            if(this.opts.next_text && (current_page < np-1 || this.opts.next_show_always)){
                fragment.append(this.createLink(current_page+1, current_page, {text:this.opts.next_text, classes:"next"}));
            }
            $('a', fragment).click(eventHandler);
            return fragment;
        }
    });

    // Extend jQuery
    $.fn.pagination = function(maxentries, opts){

        // Initialize options with default values
        opts = jQuery.extend({
            items_per_page:10,
            num_display_entries:11,
            current_page:0,
            num_edge_entries:0,
            link_to:"#",
            prev_text:"Prev",
            next_text:"Next",
            ellipse_text:"...",
            prev_show_always:true,
            next_show_always:true,
            renderer:"defaultRenderer",
            callback:function(){return false;}
        },opts||{});

        var containers = this,
            renderer, links, current_page;

        /**
         * This is the event handling function for the pagination links.
         * @param {int} page_id The new page number
         */
        function paginationClickHandler(evt){
            var links,
                new_current_page = $(evt.target).data('page_id'),
                continuePropagation = selectPage(new_current_page);
            if (!continuePropagation) {
                evt.stopPropagation();
            }
            return continuePropagation;
        }

        /**
         * This is a utility function for the internal event handlers.
         * It sets the new current page on the pagination container objects,
         * generates a new HTMl fragment for the pagination links and calls
         * the callback function.
         */
        function selectPage(new_current_page) {
            // update the link display of a all containers
            containers.data('current_page', new_current_page);
            links = renderer.getLinks(new_current_page, paginationClickHandler);
            containers.empty();
            links.appendTo(containers);
            // call the callback and propagate the event if it does not return false
            var continuePropagation = opts.callback(new_current_page, containers);
            return continuePropagation;
        }

        // -----------------------------------
        // Initialize containers
        // -----------------------------------
        current_page = opts.current_page;
        containers.data('current_page', current_page);
        // Create a sane value for maxentries and items_per_page
        maxentries = (!maxentries || maxentries < 0)?1:maxentries;
        opts.items_per_page = (!opts.items_per_page || opts.items_per_page < 0)?1:opts.items_per_page;

        if(!$.PaginationRenderers[opts.renderer])
        {
            throw new ReferenceError("Pagination renderer '" + opts.renderer + "' was not found in jQuery.PaginationRenderers object.");
        }
        renderer = new $.PaginationRenderers[opts.renderer](maxentries, opts);

        // Attach control events to the DOM elements
        var pc = new $.PaginationCalculator(maxentries, opts);
        var np = pc.numPages();
        containers.bind('setPage', {numPages:np}, function(evt, page_id) {
                if(page_id >= 0 && page_id < evt.data.numPages) {
                    selectPage(page_id); return false;
                }
        });
        containers.bind('prevPage', function(evt){
                var current_page = $(this).data('current_page');
                if (current_page > 0) {
                    selectPage(current_page - 1);
                }
                return false;
        });
        containers.bind('nextPage', {numPages:np}, function(evt){
                var current_page = $(this).data('current_page');
                if(current_page < evt.data.numPages - 1) {
                    selectPage(current_page + 1);
                }
                return false;
        });

        // When all initialisation is done, draw the links
        links = renderer.getLinks(current_page, paginationClickHandler);
        containers.empty();
        links.appendTo(containers);
        // call callback function
        opts.callback(current_page, containers);
    } // End of $.fn.pagination block

})(jQuery);

Could oyu help me with that

Body:
https://github.com/gbirke/jquery_pagination

Available Options

next_show_always

If this is set to false, the "Next"-link is only shown when the page number can be increased. Default: true

prev_show_always

If this is set to false, the "Previous"-link is only shown when the page number can be decreased. Default: true

num_display_entries

Maximum number of pagination links that are visible. Set to 0 to display a simple "Previous/Next"-Navigation. Set to an odd number for maximum symmetry and aesthetic pleasure. Default: 11

if (content.length<perPage){
//pass those options to the class
}

EDIT and since apparantly giving the solution isn't enough, I've put the all the code neatly together for you to just copy&paste now:

Less than number of items per page:
http://jsfiddle.net/niklasvh/EQVBv/

More than number of items per page:
http://jsfiddle.net/niklasvh/EQVBv/20/


来源: stackexchange

问:
How to find minimum sum of elements in a matrix python
How do I compute the minimum sum of elements in a matrix python?
for example:

```<code>z =
np.array([[1, 2, 3],

 [3, 2, 5],

 [2, 4, 4]])
</code>```

The minimum sum of the element is : 1+2+2 = 5

I tried:

```<code>def calculate(a):
    sum = 0
    for i in range(len(a)):
        sum += np.sum(a[i])

    return sum
</code>```

but it gives me 26 instead of 5

答:
So, you've z as the following array. In NumPy, you've to understand axis of the array: (please see this answer for a better mental image: very-basic-numpy-array-dimension-visualization ). So, the array here is 2D.

```<code>#----> axis: 1      #| a
array([[1, 2, 3],   #| x
       [3, 2, 5],   #| i
       [2, 4, 4]])  #| s
                    #v 0
</code>```

So, we find minimum along axis 1

```<code>In [70]: np.min(z, axis=1)
Out[70]: array([1, 2, 2])
</code>```

And since you also need sum, you call .sum() on the resulting 1D array from the above step. Below is the code in a single line:

```<code>In [71]: np.min(z, axis=1).sum()
Out[71]: 5
</code>```

A general rule of thumb would be to not use for loops with NumPy arrays since that would be awfully slow (in terms of runtime).

ContentLicense: CC BY-SA 4.0

Body:
How do I compute the minimum sum of elements in a matrix python?
for example:

z =
np.array([[1, 2, 3],

 [3, 2, 5],

 [2, 4, 4]])

The minimum sum of the element is : 1+2+2 = 5

I tried:

def calculate(a):
    sum = 0
    for i in range(len(a)):
        sum += np.sum(a[i])

    return sum

but it gives me 26 instead of 5

Body:
So, you've z as the following array. In NumPy, you've to understand axis of the array: (please see this answer for a better mental image: very-basic-numpy-array-dimension-visualization ). So, the array here is 2D.

#----> axis: 1      #| a
array([[1, 2, 3],   #| x
       [3, 2, 5],   #| i
       [2, 4, 4]])  #| s
                    #v 0

So, we find minimum along axis 1

In [70]: np.min(z, axis=1)
Out[70]: array([1, 2, 2])

And since you also need sum, you call .sum() on the resulting 1D array from the above step. Below is the code in a single line:

In [71]: np.min(z, axis=1).sum()
Out[71]: 5

A general rule of thumb would be to not use for loops with NumPy arrays since that would be awfully slow (in terms of runtime).


问:
How to test component with API call in react?
I am having trouble with testing react component that fetch data from API and renders on screen.
This is the error that I get.

     ● Company Details › renders company details with given data

    expect(received).toMatch(expected)

    Expected substring: "Google"
    Received string:    "no name provided"

      18 |     );
      19 |
    > 20 |     expect(getByTestId('company-name').textContent).toMatch('Google');
         |                                                     ^
      21 |     expect(getByTestId('sponsors-visa').textContent).toMatch('Yes');
      22 |     expect(getByTestId('description').textContent).toMatch('this is a company description');
      23 |   });

      at Object.<anonymous> (src/tests/components/company-detail/CompanyDetail.test.js:20:53)
```

<p>My test file <code>CompanyDetail.test.js</code> code :</p>

<pre class="lang-js prettyprint-override"><code>    import React from 'react';
    import CompanyDetail from '../../../components/company-detail/CompanyDetail';
    import { BrowserRouter } from 'react-router-dom';
    import { render } from '@testing-library/react';
    describe('Company Details', () => {
      let mockData;
      beforeEach(() => {
        mockData = { match: { params: { id: 4 } } };
        jest.mock('../../../components/effects/use-fetch.effect');
      });

      it('renders company details with given data', async () => {
        const { getByTestId } = render(
          <BrowserRouter>
            <CompanyDetail {...mockData} />,
          </BrowserRouter>
        );

        expect(getByTestId('company-name').textContent).toMatch('Google');
        expect(getByTestId('sponsors-visa').textContent).toMatch('Yes');
        expect(getByTestId('description').textContent).toMatch('this is a company description');
      });
    });
</code>```

Code that I want to test (CompanyDetail.js)

```<code>    import CONSTANTS from '../../constants/constants';
    import { Link } from 'react-router-dom';
    import useFetch from '../effects/use-fetch.effect';

    const CompanyDetail = (props) => {
      const { id } = props.match.params;
      const { name, description, jobs, known_to_sponsor_visa } = useFetch(`${CONSTANTS.BASE_URL}/companies/${id}`);
      return (
        <React.Fragment>
          <Container>
            <Row className="m-2">
              <Col>
                <Card>
                  <Card.Body>
                    <Card.Title>
                      <h3 data-testid="company-name">{name ? name : 'no name provided'}</h3>
                    </Card.Title>
                    <Card.Text data-testid="sponsors-visa">
                      <b>Known to sponsor work visa: </b>
                      {known_to_sponsor_visa ? known_to_sponsor_visa : 'No data'}
                    </Card.Text>
                    <Card.Text data-test-id="description">{description}</Card.Text>
                  </Card.Body>
                </Card>
              </Col>
            </Row>
          </Container>
        </React.Fragment>
      );
    };

    export default CompanyDetail;

</code>```

Just in case if it needs use-fetch.effect.js:

    import { useState, useEffect } from 'react';

    const useFetch = (url) => {
      const [dataArray, setData] = useState([]);

      useEffect(() => {
        try {
          const fetchData = async () => {
            const res = await fetch(url);
            const dataArray = await res.json();
            setData(dataArray.data)
          }
          fetchData();

        } catch (err) {
          console.error(err);
        }
      }, [url]);

      return dataArray;
    };

    export default useFetch;
```

I could test it by sending data via props but I have no idea how can I mock data to test that url to receive id and render it into specific place. Any help would be appreciated. I know why error is there because i have not passed any company name as Google to check. Problem is how can i test that by passing some dummy data .

答:
Since useFetch is expected to be asynchronous any way and this may affect how the component works, it needs to be mocked in more complicated way than Jest spy that returns a value. The request itself can be mocked instead of entire useFetch:

```<code>let data = { name: 'Google', ... };
spyOn(global, 'fetch').mockResolvedValue({ json: jest.fn().mockResolvedValue({ data }) });

...

expect(getByTestId('company-name').textContent).toMatch('no name provided');
await waitFor(() => expect(getByTestId('company-name').textContent).toMatch('Google'));
</code>```

Body:
I am having trouble with testing react component that fetch data from API and renders on screen.
This is the error that I get.

     ● Company Details › renders company details with given data

    expect(received).toMatch(expected)

    Expected substring: "Google"
    Received string:    "no name provided"

      18 |     );
      19 |
    > 20 |     expect(getByTestId('company-name').textContent).toMatch('Google');
         |                                                     ^
      21 |     expect(getByTestId('sponsors-visa').textContent).toMatch('Yes');
      22 |     expect(getByTestId('description').textContent).toMatch('this is a company description');
      23 |   });

      at Object.<anonymous> (src/tests/components/company-detail/CompanyDetail.test.js:20:53)

My test file CompanyDetail.test.js code :

    import React from 'react';
    import CompanyDetail from '../../../components/company-detail/CompanyDetail';
    import { BrowserRouter } from 'react-router-dom';
    import { render } from '@testing-library/react';
    describe('Company Details', () => {
      let mockData;
      beforeEach(() => {
        mockData = { match: { params: { id: 4 } } };
        jest.mock('../../../components/effects/use-fetch.effect');
      });

      it('renders company details with given data', async () => {
        const { getByTestId } = render(
          <BrowserRouter>
            <CompanyDetail {...mockData} />,
          </BrowserRouter>
        );

        expect(getByTestId('company-name').textContent).toMatch('Google');
        expect(getByTestId('sponsors-visa').textContent).toMatch('Yes');
        expect(getByTestId('description').textContent).toMatch('this is a company description');
      });
    });

Code that I want to test (CompanyDetail.js)

    import CONSTANTS from '../../constants/constants';
    import { Link } from 'react-router-dom';
    import useFetch from '../effects/use-fetch.effect';

    const CompanyDetail = (props) => {
      const { id } = props.match.params;
      const { name, description, jobs, known_to_sponsor_visa } = useFetch(`${CONSTANTS.BASE_URL}/companies/${id}`);
      return (
        <React.Fragment>
          <Container>
            <Row className="m-2">
              <Col>
                <Card>
                  <Card.Body>
                    <Card.Title>

{name ? name : 'no name provided'}

                    </Card.Title>
                    <Card.Text data-testid="sponsors-visa">
                      Known to sponsor work visa:
                      {known_to_sponsor_visa ? known_to_sponsor_visa : 'No data'}
                    </Card.Text>
                    <Card.Text data-test-id="description">{description}</Card.Text>
                  </Card.Body>
                </Card>
              </Col>
            </Row>
          </Container>
        </React.Fragment>
      );
    };

    export default CompanyDetail;

Just in case if it needs use-fetch.effect.js:

    import { useState, useEffect } from 'react';

    const useFetch = (url) => {
      const [dataArray, setData] = useState([]);

      useEffect(() => {
        try {
          const fetchData = async () => {
            const res = await fetch(url);
            const dataArray = await res.json();
            setData(dataArray.data)
          }
          fetchData();

        } catch (err) {
          console.error(err);
        }
      }, [url]);

      return dataArray;
    };

    export default useFetch;

I could test it by sending data via props but I have no idea how can I mock data to test that url to receive id and render it into specific place. Any help would be appreciated. I know why error is there because i have not passed any company name as Google to check. Problem is how can i test that by passing some dummy data .

Body:
Since useFetch is expected to be asynchronous any way and this may affect how the component works, it needs to be mocked in more complicated way than Jest spy that returns a value. The request itself can be mocked instead of entire useFetch:

let data = { name: 'Google', ... };
spyOn(global, 'fetch').mockResolvedValue({ json: jest.fn().mockResolvedValue({ data }) });

...

expect(getByTestId('company-name').textContent).toMatch('no name provided');
await waitFor(() => expect(getByTestId('company-name').textContent).toMatch('Google'));


问:
Verifying duplicate objects in array of objects using JavaScript
I am having array of objects in a following form,

```<code>let test = [
{
 RowCreationMethod: "excel",
 deviceID: "123ECd9",
 deviceName: "ZENW42NLPC0378",
 devicePrimary: "Yes",
 deviceType: "Laptop",
 employeeID: 101,
 isExists: "No",
 isRescheduled: "No",
 vipUser: "Yes"
 },{
 RowCreationMethod: "excel",
 deviceName: "ZENW42NLPC0378",
 devicePrimary: "Yes",
 deviceType: "Laptop",
 deviceID: "123ECd9",
 employeeID: 101,
 isExists: "No",
 isRescheduled: "No",
 vipUser: "Yes"
 }];
</code>```

I have written following code to check if their exits any duplicate object in my array its working but if I changes the sequence of any object properties then its not working, because in my code I am converting objects to string and verifying it.

Here is my code

```<code>let final = []
test.forEach(x => {
  if(!final.some(y => JSON.stringify(y) === JSON.stringify(x))){
    final.push(x)
  }
})
</code>```

答:
You could create a Set of every key in the array. Then, use reduce to group the array based on a unique value string for the each object. i.e. a string with the values of an object separated by | in the same order as allKeys. For example, for the given 2 objects, it will look like this:

```<code>"excel|123ECd9|ZENW42NLPC0378|Yes|Laptop|101|No|No|Yes"
</code>```

If another object has the same string, it will be overwritten in the accumulator object.

This will work even if some objects have missing keys

var test=[{RowCreationMethod:"excel",deviceID:"123ECd9",deviceName:"ZENW42NLPC0378",devicePrimary:"Yes",deviceType:"Laptop",employeeID:101,isExists:"No",isRescheduled:"No",vipUser:"Yes"},{RowCreationMethod:"excel",deviceName:"ZENW42NLPC0378",devicePrimary:"Yes",deviceType:"Laptop",deviceID:"123ECd9",employeeID:101,isExists:"No",isRescheduled:"No",vipUser:"Yes"}];

function uniqueObjects(array) {
  const set = new Set(array.flatMap(Object.keys)),
        allKeys = Array.from(set);

  const group = array.reduce((acc, o) => {
    const unique = allKeys.map(k => o[k]).join('|');
    acc[unique] = o;
    return acc
  }, {})

  return Object.values(group)
}

console.log(uniqueObjects(test))```
</div>
</div>
</p>

<p>If every object has the same set of keys, you can skip the <code>Set</code> step and replace it with</p>

```const allKeys = Object.keys(array[0])
```

Body:
I am having array of objects in a following form,

let test = [
{
 RowCreationMethod: "excel",
 deviceID: "123ECd9",
 deviceName: "ZENW42NLPC0378",
 devicePrimary: "Yes",
 deviceType: "Laptop",
 employeeID: 101,
 isExists: "No",
 isRescheduled: "No",
 vipUser: "Yes"
 },{
 RowCreationMethod: "excel",
 deviceName: "ZENW42NLPC0378",
 devicePrimary: "Yes",
 deviceType: "Laptop",
 deviceID: "123ECd9",
 employeeID: 101,
 isExists: "No",
 isRescheduled: "No",
 vipUser: "Yes"
 }];

I have written following code to check if their exits any duplicate object in my array its working but if I changes the sequence of any object properties then its not working, because in my code I am converting objects to string and verifying it.

Here is my code

let final = []
test.forEach(x => {
  if(!final.some(y => JSON.stringify(y) === JSON.stringify(x))){
    final.push(x)
  }
})

Body:
You could create a Set of every key in the array. Then, use reduce to group the array based on a unique value string for the each object. i.e. a string with the values of an object separated by | in the same order as allKeys. For example, for the given 2 objects, it will look like this:

"excel|123ECd9|ZENW42NLPC0378|Yes|Laptop|101|No|No|Yes"

If another object has the same string, it will be overwritten in the accumulator object.

This will work even if some objects have missing keys

var test=[{RowCreationMethod:"excel",deviceID:"123ECd9",deviceName:"ZENW42NLPC0378",devicePrimary:"Yes",deviceType:"Laptop",employeeID:101,isExists:"No",isRescheduled:"No",vipUser:"Yes"},{RowCreationMethod:"excel",deviceName:"ZENW42NLPC0378",devicePrimary:"Yes",deviceType:"Laptop",deviceID:"123ECd9",employeeID:101,isExists:"No",isRescheduled:"No",vipUser:"Yes"}];

function uniqueObjects(array) {
  const set = new Set(array.flatMap(Object.keys)),
        allKeys = Array.from(set);

  const group = array.reduce((acc, o) => {
    const unique = allKeys.map(k => o[k]).join('|');
    acc[unique] = o;
    return acc
  }, {})

  return Object.values(group)
}

console.log(uniqueObjects(test))

If every object has the same set of keys, you can skip the Set step and replace it with

const allKeys = Object.keys(array[0])


问:
Configuring 2008 reporting service in sql server 2005 instance
can we configure 2008 reporting service in sql server 2005 instance? will there be any compatibility issues if you do so?</p>

答:
I can tell you that from my last conversations with MS Support, it's not a officially supported configuration by Microsoft.  That having been said, I have done this a number of times and it has worked flawlessly each time -- I've used SSRS 2008 R2 against SQL 2005 very successfully.

That's not to say that it will continue to work when MS releases an SSRS service pack down the line, but I would frankly have a hard time believing that MS would release a SSRS service pack which would break this configuration.

I would say do it, but you should have a plan to migrate your SQL 2005 Database Engine instances to SQL 2008 R2 or the next upcoming version soon, as SQL 2005 mainstream support ended on April 12, 2011.

ContentLicense: CC BY-SA 3.0


问:
How can piping tail of a log to a script cause the process generating the log to stop generating entries?
I’m trying to solve a weird issue. I have evidence suggesting that the script I’m piping tail output to is the cause of the issue, but I’m not sure what to look for. Here’s what I’ve got:

I have a java program that generates a log to stdout with which I merge stderr (2>&1) and redirect to a file. I run a separate shell script that does a tail -F that pipes it to a Perl script which operates on events in the log and never exits.

It’s not the best design, but everything has worked for years until recently (the past couple months). There was an apparent problem with the jar file, as the log had built up tons of errors, so as a first step, I updated to the latest version. The new version however, in the setup I described above, stops adding entries to the log.

To narrow the issue, I have done the following:

```<code>tail -F log | perl -pne ‘$|=1;’
tail -F log
</code>```

This shows that output continues to flow and suggests that something the script is doing is causing the problem.

However, that doesn’t appear to be the whole story because when I run everything on a different computer, everything there works! It’s only on a specific computer where the jar stops printing to the log.

Other details:

The java process continues to run in all cases.

I am testing by doing a tail -F again after running everything in the background

There may have been an OS update that caused the issue

Running in a bash shell

I updated a module that the perl script uses to be the same, but there is apparently a minor difference between the computer that it works on and the one that stops the java output which I have yet to investigate

Here are the actual commands I'm using for testing:

```<code>java -cp WemoServer.jar mpp.wemo.server.Headless -p 4033 -upnp -run -log >> WemoServer.log 2>&1 &
sh -c "tail -F WemoServer.log | ./WemoServerLogProcessor.pl -r rules.txt --extended" 2>&1 >> WemoParser.log &

#And I'm testing whether the java process stops generating output via:
tail -F WemoServer.log
</code>```

I’m stumped as to how to debug this issue. What should I look for?

UPDATE: I have learned that the java process can still write to the log. I know this because if I leave it running long enough, and initial bonjour search function completes and writes a message stating as much to the log.

However, the moment I pipe a tail of the log to my script, it appears that event tries stop, such as is written when an outlet turns on or off or motion is detected. If I don’t pipe the tail of the log to my Perl script, all device events get written to the log as they happen. It’s as if the java process loses its communication ability with the devices.

I know that bonjour is used to discover the devices and it prints to the log their IP addresses, so I don’t know what the interruption could be. My Perl script definitely does nothing with ports or bonjour or anything. It just parses a file on STDIN.

I suppose I can try updating the OS since it’s 2 versions behind my laptop which works, but I’d like to understand what’s going on.

答:
I asked the wrong question.  Yes, the output was stopping, but the stopping of the output happened to be catalyzed by connecting to the output stream.  The ending of the output happens eventually even if left alone.

The real reason it was stopping is because I had 2 separate subscriptions to the Wemo device and it only supports 1.

Body:
I’m trying to solve a weird issue. I have evidence suggesting that the script I’m piping tail output to is the cause of the issue, but I’m not sure what to look for. Here’s what I’ve got:

I have a java program that generates a log to stdout with which I merge stderr (2>&1) and redirect to a file. I run a separate shell script that does a tail -F that pipes it to a Perl script which operates on events in the log and never exits.

It’s not the best design, but everything has worked for years until recently (the past couple months). There was an apparent problem with the jar file, as the log had built up tons of errors, so as a first step, I updated to the latest version. The new version however, in the setup I described above, stops adding entries to the log.

To narrow the issue, I have done the following:

tail -F log | perl -pne ‘$|=1;’
tail -F log

This shows that output continues to flow and suggests that something the script is doing is causing the problem.

However, that doesn’t appear to be the whole story because when I run everything on a different computer, everything there works! It’s only on a specific computer where the jar stops printing to the log.

Other details:

The java process continues to run in all cases.

I am testing by doing a tail -F again after running everything in the background

There may have been an OS update that caused the issue

Running in a bash shell

I updated a module that the perl script uses to be the same, but there is apparently a minor difference between the computer that it works on and the one that stops the java output which I have yet to investigate

Here are the actual commands I'm using for testing:

java -cp WemoServer.jar mpp.wemo.server.Headless -p 4033 -upnp -run -log >> WemoServer.log 2>&1 &
sh -c "tail -F WemoServer.log | ./WemoServerLogProcessor.pl -r rules.txt --extended" 2>&1 >> WemoParser.log &

#And I'm testing whether the java process stops generating output via:
tail -F WemoServer.log

I’m stumped as to how to debug this issue. What should I look for?

UPDATE: I have learned that the java process can still write to the log. I know this because if I leave it running long enough, and initial bonjour search function completes and writes a message stating as much to the log.

However, the moment I pipe a tail of the log to my script, it appears that event tries stop, such as is written when an outlet turns on or off or motion is detected. If I don’t pipe the tail of the log to my Perl script, all device events get written to the log as they happen. It’s as if the java process loses its communication ability with the devices.

I know that bonjour is used to discover the devices and it prints to the log their IP addresses, so I don’t know what the interruption could be. My Perl script definitely does nothing with ports or bonjour or anything. It just parses a file on STDIN.

I suppose I can try updating the OS since it’s 2 versions behind my laptop which works, but I’d like to understand what’s going on.


问:
java dbcp2 multithreaded connection access
I'm pretty familiar using connection pooling on tomcat & have used it for years without problem.  However at the moment I'm working on a main method application that needs to run simultaneous threads for performance reasons, and those threads each need to access the same database.  I've gotten my code to work if I strip out database code altogether & just use arrays for test purposes (e.g. multithreading works) however as soon as I add back in database connections, the first thread takes the lock and the other threads don't run at all.  Have played with c3p0, and dbcp2; currently working with dbcp2.  Thanks!  There's tons of documentation out there, but not many code samples that seem specific to my use case.  Here's a sample app:</p>

```<code>import java.sql.*;
import org.apache.commons.dbcp2.ConnectionFactory;
import org.apache.commons.dbcp2.DriverManagerConnectionFactory;
import org.apache.commons.dbcp2.PoolableConnection;
import org.apache.commons.dbcp2.PoolableConnectionFactory;
import org.apache.commons.dbcp2.PoolingDataSource;
import org.apache.commons.dbcp2.PoolingDriver;
import org.apache.commons.dbcp2.Utils;
import org.apache.commons.pool2.ObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPool;

public class SandboxApp {

    private static BasicDataSource dataSource;

    public static BasicDataSource getDataSource() {

        if (dataSource == null) {

            BasicDataSource ds = new BasicDataSource();

            ds.setUrl("jdbc:mysql://localhost:3306/my-db");
            ds.setUsername("root");
            ds.setPassword("");

            ds.setDriverClassName("org.mariadb.jdbc.Driver");

            ds.setInitialSize(3);
            ds.setMaxTotal(25);
            ds.setMinIdle(0);
            ds.setMaxIdle(8);
            ds.setMaxOpenPreparedStatements(100);

            dataSource = ds;
        }
        return dataSource;
    }

    public static void main(String [] args) throws Exception{
       for(int i=0; i<11; i++){//spawn 11 threads & get each thread to process 600k sql rows at the same time
              new Thread("" + (i*600000)){

                public void run(){
                    System.out.println("Thread: " + getName() + " running");//prints correctly for all threads

                    Connection con = null;
                    PreparedStatement pstmt = null;
                    ResultSet rs = null;
                try {
                    con = SandboxApp.getDataSource().getConnection();

                    pstmt = con.prepareStatement("select something from some_table limit "+getName()+",600000");
                    rs=pstmt.executeQuery();
                    while(rs.next()){
                        System.out.println("Doing stuff for thread "+getName());//this only prints for getName() == 0
                            //give the other threads a turn...
                            try {
                                Thread.sleep(10);
                            }
                            catch(InterruptedException ex) {
                            }
                    }

                  } catch (Exception e) {
                    e.printStackTrace();
                  }finally{
                      try {pstmt.close();} catch (SQLException e) {}
                      try { con.close(); } catch(Exception e) {}
                      try { rs.close(); } catch(Exception e) {}
                  }
                }
              }.start();
        }
    }
}
</code>```

答:
@user207421 was right, that the getDataSource() method should be synchronized & of course I'd already tried this; however this still didn't solve for my problem of thread "0" not letting the other threads take a turn.

I stripped back everything from my code, all other libraries etc.. until I got it to work, and then started building it back up again to find the breaking point.  It seems that the main determining factor is the size of the ResultSet.  I tried adding in extra thread.sleep time in various places however the only thing that has worked is breaking down the queries to request smaller ResultSets.

600k result sets, only 1 thread will run, 1k ResultSets and 4 threads will run.  With ResultSets containing only 100 rows, all 11 threads will run.  Note, I was testing this on a 16 CPU system with 8GB of memory allocated to the JVM (aws m5.4xlarge), so hardware resources shouldn't have been a contributing factor.  So I guess I'll just have to break my code into smaller chunks.

When I was initially looking into this I was surprised as to the lack of a specific code samples for this specific problem (irrespective of ResultSet size & number of threads), so I'm just posting here what finally worked for me for the sake of a complete code sample:

```<code>    import java.sql.*;
    import org.apache.commons.dbcp2.BasicDataSource;

    public class SandboxApp {

        private static BasicDataSource dataSource;

        public static synchronized BasicDataSource getDataSource() {

            if (dataSource == null) {

                BasicDataSource ds = new BasicDataSource();

                ds.setUrl("jdbc:mysql://localhost:3306/my-db");
                ds.setUsername("root");
                ds.setPassword("");

                ds.setDriverClassName("org.mariadb.jdbc.Driver");

                ds.setInitialSize(3);
                ds.setMaxTotal(25);
                ds.setMinIdle(0);
                ds.setMaxIdle(8);
                ds.setMaxOpenPreparedStatements(100);

                dataSource = ds;
            }
            return dataSource;
        }

        public static void main(String [] args) throws Exception{
           for(int i=0; i<11; i++){//spawn 11 threads & get each thread to process 100 sql rows at the same time
                  new Thread("" + (i*100)){

                    public void run(){
                        System.out.println("Thread: " + getName() + " running");

                        Connection con = null;
                        PreparedStatement pstmt = null;
                        ResultSet rs = null;
                    try {
                        con = SandboxApp.getDataSource().getConnection();

                        pstmt = con.prepareStatement("select something from some_table limit "+getName()+",100");
                        rs=pstmt.executeQuery();
                        while(rs.next()){
                            System.out.println("Doing stuff for thread "+getName());//With smaller ResultSet, this works fine for all 11 threads
                                //give the other threads a turn...
                                try {
                                    Thread.sleep(10);
                                }
                                catch(InterruptedException ex) {
                                }
                        }

                      } catch (Exception e) {
                        e.printStackTrace();
                      }finally{
                          try {pstmt.close();} catch (SQLException e) {}
                          try { con.close(); } catch(Exception e) {}
                          try { rs.close(); } catch(Exception e) {}
                      }
                    }
                  }.start();
            }
        }
    }
</code>```

Body:
I'm pretty familiar using connection pooling on tomcat & have used it for years without problem.  However at the moment I'm working on a main method application that needs to run simultaneous threads for performance reasons, and those threads each need to access the same database.  I've gotten my code to work if I strip out database code altogether & just use arrays for test purposes (e.g. multithreading works) however as soon as I add back in database connections, the first thread takes the lock and the other threads don't run at all.  Have played with c3p0, and dbcp2; currently working with dbcp2.  Thanks!  There's tons of documentation out there, but not many code samples that seem specific to my use case.  Here's a sample app:

import java.sql.*;
import org.apache.commons.dbcp2.ConnectionFactory;
import org.apache.commons.dbcp2.DriverManagerConnectionFactory;
import org.apache.commons.dbcp2.PoolableConnection;
import org.apache.commons.dbcp2.PoolableConnectionFactory;
import org.apache.commons.dbcp2.PoolingDataSource;
import org.apache.commons.dbcp2.PoolingDriver;
import org.apache.commons.dbcp2.Utils;
import org.apache.commons.pool2.ObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPool;

public class SandboxApp {

    private static BasicDataSource dataSource;

    public static BasicDataSource getDataSource() {

        if (dataSource == null) {

            BasicDataSource ds = new BasicDataSource();

            ds.setUrl("jdbc:mysql://localhost:3306/my-db");
            ds.setUsername("root");
            ds.setPassword("");

            ds.setDriverClassName("org.mariadb.jdbc.Driver");

            ds.setInitialSize(3);
            ds.setMaxTotal(25);
            ds.setMinIdle(0);
            ds.setMaxIdle(8);
            ds.setMaxOpenPreparedStatements(100);

            dataSource = ds;
        }
        return dataSource;
    }

    public static void main(String [] args) throws Exception{
       for(int i=0; i<11; i++){//spawn 11 threads & get each thread to process 600k sql rows at the same time
              new Thread("" + (i*600000)){

                public void run(){
                    System.out.println("Thread: " + getName() + " running");//prints correctly for all threads

                    Connection con = null;
                    PreparedStatement pstmt = null;
                    ResultSet rs = null;
                try {
                    con = SandboxApp.getDataSource().getConnection();

                    pstmt = con.prepareStatement("select something from some_table limit "+getName()+",600000");
                    rs=pstmt.executeQuery();
                    while(rs.next()){
                        System.out.println("Doing stuff for thread "+getName());//this only prints for getName() == 0
                            //give the other threads a turn...
                            try {
                                Thread.sleep(10);
                            }
                            catch(InterruptedException ex) {
                            }
                    }

                  } catch (Exception e) {
                    e.printStackTrace();
                  }finally{
                      try {pstmt.close();} catch (SQLException e) {}
                      try { con.close(); } catch(Exception e) {}
                      try { rs.close(); } catch(Exception e) {}
                  }
                }
              }.start();
        }
    }
}

Body:
@user207421 was right, that the getDataSource() method should be synchronized & of course I'd already tried this; however this still didn't solve for my problem of thread "0" not letting the other threads take a turn.

I stripped back everything from my code, all other libraries etc.. until I got it to work, and then started building it back up again to find the breaking point.  It seems that the main determining factor is the size of the ResultSet.  I tried adding in extra thread.sleep time in various places however the only thing that has worked is breaking down the queries to request smaller ResultSets.

600k result sets, only 1 thread will run, 1k ResultSets and 4 threads will run.  With ResultSets containing only 100 rows, all 11 threads will run.  Note, I was testing this on a 16 CPU system with 8GB of memory allocated to the JVM (aws m5.4xlarge), so hardware resources shouldn't have been a contributing factor.  So I guess I'll just have to break my code into smaller chunks.

When I was initially looking into this I was surprised as to the lack of a specific code samples for this specific problem (irrespective of ResultSet size & number of threads), so I'm just posting here what finally worked for me for the sake of a complete code sample:

    import java.sql.*;
    import org.apache.commons.dbcp2.BasicDataSource;

    public class SandboxApp {

        private static BasicDataSource dataSource;

        public static synchronized BasicDataSource getDataSource() {

            if (dataSource == null) {

                BasicDataSource ds = new BasicDataSource();

                ds.setUrl("jdbc:mysql://localhost:3306/my-db");
                ds.setUsername("root");
                ds.setPassword("");

                ds.setDriverClassName("org.mariadb.jdbc.Driver");

                ds.setInitialSize(3);
                ds.setMaxTotal(25);
                ds.setMinIdle(0);
                ds.setMaxIdle(8);
                ds.setMaxOpenPreparedStatements(100);

                dataSource = ds;
            }
            return dataSource;
        }

        public static void main(String [] args) throws Exception{
           for(int i=0; i<11; i++){//spawn 11 threads & get each thread to process 100 sql rows at the same time
                  new Thread("" + (i*100)){

                    public void run(){
                        System.out.println("Thread: " + getName() + " running");

                        Connection con = null;
                        PreparedStatement pstmt = null;
                        ResultSet rs = null;
                    try {
                        con = SandboxApp.getDataSource().getConnection();

                        pstmt = con.prepareStatement("select something from some_table limit "+getName()+",100");
                        rs=pstmt.executeQuery();
                        while(rs.next()){
                            System.out.println("Doing stuff for thread "+getName());//With smaller ResultSet, this works fine for all 11 threads
                                //give the other threads a turn...
                                try {
                                    Thread.sleep(10);
                                }
                                catch(InterruptedException ex) {
                                }
                        }

                      } catch (Exception e) {
                        e.printStackTrace();
                      }finally{
                          try {pstmt.close();} catch (SQLException e) {}
                          try { con.close(); } catch(Exception e) {}
                          try { rs.close(); } catch(Exception e) {}
                      }
                    }
                  }.start();
            }
        }
    }


问:
How to make a loop to link a textbox content to a specific excel sheet with Excel VBA
i created a userform for tracking the consumption of a set of products in a warehouse, where the content of each text box will be assigned to a different excel sheet (saving the consumption history)
i would like to ask if it's possible to make a loop for assigning the content of each textbox to a specific sheet instead of repeating the code several times.<br>
i will be really grateful for your help
Thank you </p>

```<code> Private Sub CommandButton1_Click()

Dim consobav, consobls, consochar As Worksheet
Dim addnewbav, addnewbls, addnewchar As Range
Dim nombrebavettes, nombreblouses, qttbavettes, qttblouses As Integer

Set consobav = Sheet1
Set consobls = Sheet2
Set consochar = Sheet3
'introduire le nombre introduit dans la text box dans le sheet excel
If nbrbavette.Value = "" Then
qttbavettes = 0
Else
nombrebavettes = CInt(ThisWorkbook.Sheets("sheet1").Range("H2").Value)
qttbavettes = CInt(nbrbavette.Value)
End If
If nombrebavettes < qttbavettes Then
MsgBox "qtt insuffisante: " & ThisWorkbook.Sheets("sheet1").Range("A1").Value
Else
Set addnewbav = consobav.Range("A65356").End(xlUp).Offset(1, 0)
addnewbav.Offset(0, 0).Value = qttbavettes
addnewbav.Offset(0, 1).Value = Time & " " & Date
addnewbav.Offset(0, 1).NumberFormat = "d/m/yyyy"
End If

If nbrbls.Value = "" Then
qttblouses = 0
Else
nombreblouses = CInt(ThisWorkbook.Sheets("sheet2").Range("H2").Value)
qttblouses = CInt(nbrbls.Value)
End If
If nombreblouses < qttblouses Then

MsgBox "qtt insuffisante : " & ThisWorkbook.Sheets("sheet2").Range("A1").Value
Else
Set addnewbls = consobls.Range("A65356").End(xlUp).Offset(1, 0)
addnewbls.Offset(0, 0).Value = qttblouses
addnewbls.Offset(0, 1).Value = Time & " " & Date
addnewbls.Offset(0, 1).NumberFormat = "d/m/yyyy"
End If

Set addnewchar = consochar.Range("A65356").End(xlUp).Offset(1, 0)
addnewchar.Offset(0, 0).Value = TextBox1.Value
addnewchar.Offset(0, 1).Value = Time & " " & Date
addnewchar.Offset(0, 1).NumberFormat = "d/m/yyyy"

Call display
Call Somme_consommation_globale
Call seuil_commande
Call display
Call resetform
Call saving_PDF

End Sub
</code>```

答:
I think the next code can be the solution for your problem.
Please let me note that your statement:
Dim consobav, consobls, consochar As Worksheet shows a frequent mistake: consobav and consobls are type variant and only consochar is worksheet.
Correctly Dim consobav As Worksheet, consobls As Worksheet, consochar As Worksheet
The same is in the next two lines.

```<code>Option Base 1
Private Sub mySub()
    Dim tbAllBoxes() As Variant
    'Put all you textboxes into an array
    tbAllBoxes = Array(ManyText.Controls("Textbox1"), ManyText.Controls("Textbox2"), ManyText.Controls("Textbox3"), ManyText.Controls("Textbox4"))

    Dim shAllSheets As Variant
    'Put all your worksheets into an array
    shAllSheets = Array(Worksheets("1"), Worksheets("2"), Worksheets("3"), Worksheets("4"))
    Dim i As Long
    'Use the pair of textboxes and worksheets
    For i = 1 To UBound(tbAllBoxes)
        ' Example: write the content of textboxes in the sheets in order Textbox1 to worksheet("1")
        shAllSheets(i).Range("A2") = tbAllBoxes(i).Text
        'do whatever you would like
    Next i
End Sub
</code>```

Body:
i created a userform for tracking the consumption of a set of products in a warehouse, where the content of each text box will be assigned to a different excel sheet (saving the consumption history)
i would like to ask if it's possible to make a loop for assigning the content of each textbox to a specific sheet instead of repeating the code several times.

i will be really grateful for your help
Thank you

 Private Sub CommandButton1_Click()

Dim consobav, consobls, consochar As Worksheet
Dim addnewbav, addnewbls, addnewchar As Range
Dim nombrebavettes, nombreblouses, qttbavettes, qttblouses As Integer

Set consobav = Sheet1
Set consobls = Sheet2
Set consochar = Sheet3
'introduire le nombre introduit dans la text box dans le sheet excel
If nbrbavette.Value = "" Then
qttbavettes = 0
Else
nombrebavettes = CInt(ThisWorkbook.Sheets("sheet1").Range("H2").Value)
qttbavettes = CInt(nbrbavette.Value)
End If
If nombrebavettes < qttbavettes Then
MsgBox "qtt insuffisante: " & ThisWorkbook.Sheets("sheet1").Range("A1").Value
Else
Set addnewbav = consobav.Range("A65356").End(xlUp).Offset(1, 0)
addnewbav.Offset(0, 0).Value = qttbavettes
addnewbav.Offset(0, 1).Value = Time & " " & Date
addnewbav.Offset(0, 1).NumberFormat = "d/m/yyyy"
End If

If nbrbls.Value = "" Then
qttblouses = 0
Else
nombreblouses = CInt(ThisWorkbook.Sheets("sheet2").Range("H2").Value)
qttblouses = CInt(nbrbls.Value)
End If
If nombreblouses < qttblouses Then

MsgBox "qtt insuffisante : " & ThisWorkbook.Sheets("sheet2").Range("A1").Value
Else
Set addnewbls = consobls.Range("A65356").End(xlUp).Offset(1, 0)
addnewbls.Offset(0, 0).Value = qttblouses
addnewbls.Offset(0, 1).Value = Time & " " & Date
addnewbls.Offset(0, 1).NumberFormat = "d/m/yyyy"
End If

Set addnewchar = consochar.Range("A65356").End(xlUp).Offset(1, 0)
addnewchar.Offset(0, 0).Value = TextBox1.Value
addnewchar.Offset(0, 1).Value = Time & " " & Date
addnewchar.Offset(0, 1).NumberFormat = "d/m/yyyy"

Call display
Call Somme_consommation_globale
Call seuil_commande
Call display
Call resetform
Call saving_PDF

End Sub

Body:
I think the next code can be the solution for your problem.
Please let me note that your statement:
Dim consobav, consobls, consochar As Worksheet shows a frequent mistake: consobav and consobls are type variant and only consochar is worksheet.
Correctly Dim consobav As Worksheet, consobls As Worksheet, consochar As Worksheet
The same is in the next two lines.

Option Base 1
Private Sub mySub()
    Dim tbAllBoxes() As Variant
    'Put all you textboxes into an array
    tbAllBoxes = Array(ManyText.Controls("Textbox1"), ManyText.Controls("Textbox2"), ManyText.Controls("Textbox3"), ManyText.Controls("Textbox4"))

    Dim shAllSheets As Variant
    'Put all your worksheets into an array
    shAllSheets = Array(Worksheets("1"), Worksheets("2"), Worksheets("3"), Worksheets("4"))
    Dim i As Long
    'Use the pair of textboxes and worksheets
    For i = 1 To UBound(tbAllBoxes)
        ' Example: write the content of textboxes in the sheets in order Textbox1 to worksheet("1")
        shAllSheets(i).Range("A2") = tbAllBoxes(i).Text
        'do whatever you would like
    Next i
End Sub


问:
Getting practice with pandas & numpy
I just finished reading some books about pandas, numpy & matplotlib and thought about getting some practice.
Unfortunately, I am a bit lost on how to start.
Can anyone recommend a site, which provides csv-files to practice on?
I have found some sites like kaggle or data.gov, but they just have files, which are already cleaned etc.
I'm also open to other ways on how to practice those libraries.
Grateful for every answer.
Best regards  </p>

答:
Just Search the Web. Using e.g. Google seach for Pandas tutorial,
Numpy tutorial and so on.

Even the home site of matplotlib contains a couple of introductory
tutorials. See e.g. https://matplotlib.org/tutorials/index.html

A good source of knowledge is also stackoverflow itself.

Title: Getting practice with pandas & numpy


问:
Laravel 419 error using Uppy open source, how to add csrf token to Uppy?
Before some of you mark this as duplicate since error 419 using laravel has been answered a million times, this is a bit more complicated and I cant seem to work around it.

I am trying to use Uppy to upload some images however I cant seem to find a way to add the csrf token to Uppy. (https://uppy.io/docs/tus/#headers)

```<code>const uppy = Uppy();
uppy.use(Dashboard, { target: '#drag-drop-area', inline: true, height: 450 });
uppy.use(Tus, {
     header: 'X-CSRF-TOKEN'+document.querySelector('[name=csrf-token]').getAttribute('content'),
     endpoint: 'https://mysitev/tus', // use your tus endpoint here
     resume: true,
     autoRetry: true,
     retryDelays: [0, 1000, 3000, 5000]
})
</code>```

Does anyone has used Uppy in the past and if so how did you include the csrf_token?

Thanks

答:
Try with it:</p>

```<code>uppy.use(Uppy.Tus, {
    endpoint: '{{ $endpoint }}',
    headers: {
        'X-CSRF-Token': " {{ csrf_token() }} "
    }
})
</code>```

Body:
Before some of you mark this as duplicate since error 419 using laravel has been answered a million times, this is a bit more complicated and I cant seem to work around it.

I am trying to use Uppy to upload some images however I cant seem to find a way to add the csrf token to Uppy. (https://uppy.io/docs/tus/#headers)

const uppy = Uppy();
uppy.use(Dashboard, { target: '#drag-drop-area', inline: true, height: 450 });
uppy.use(Tus, {
     header: 'X-CSRF-TOKEN'+document.querySelector('[name=csrf-token]').getAttribute('content'),
     endpoint: 'https://mysitev/tus', // use your tus endpoint here
     resume: true,
     autoRetry: true,
     retryDelays: [0, 1000, 3000, 5000]
})

Does anyone has used Uppy in the past and if so how did you include the csrf_token?

Thanks

Body:
Try with it:

uppy.use(Uppy.Tus, {
    endpoint: '{{ $endpoint }}',
    headers: {
        'X-CSRF-Token': " {{ csrf_token() }} "
    }
})


问:
Login Required decorator not redirecting to login url | Django
@login_required decorator not redirecting me to the login page

When I click the add to cart button it doesn't redirect me to the login page. It just doesn't do anything. I tried the login required decorator in another function. Like the home view action. And when I try to access the home page it directly redirects me to the login page. But in the combo_add_to_cart it doesn't seems to work. But I have found something in the terminal. I have seen that when I click the add to cart button it first sends a post request of "POST /carts/cart/combo/add-to-cart/ " then it sends a get request "GET /accounts/login/?next=/carts/cart/combo/add-to-cart/"

accounts views.py

```<code>class Login(FormView):
    form_class = LoginForm
    success_url = '/'
    template_name = 'accounts/login.html'

    def form_valid(self, form):
        request = self.request
        next_ = request.GET.get('next')
        next_post = request.POST.get('next')
        redirect_path = next_ or next_post or None
        email = form.cleaned_data.get('email')
        password = form.cleaned_data.get('password')
        user = authenticate(request, email=email, password=password)
        if user is not None:
            login(request, user)
            if is_safe_url(redirect_path, request.get_host()):
                return redirect(redirect_path)
            else:
                return redirect("/")
        return super(Login, self).form_invalid(form)
</code>```

cart views.py

```<code>@login_required(login_url='/accounts/login/')
def combo_add_to_cart(request):
    combo_id = request.POST.get('combo_id')
    if combo_id is not None:
        try:
            combo_obj = Combo.objects.get(id=combo_id)
        except Combo.DoesNotExist:
            return("carts:cart")

        combo = combo_obj

        cart_item, created = ComboCartItem.objects.get_or_create(
            combo=combo,
            user=request.user,
            ordered=False
        )

        cart_obj, new_obj = Cart.objects.new_or_get(request)

        if cart_obj.combo_item.filter(combo__id=combo.id).exists():
            cart_item.quantity += 1
            cart_item.save()
            print("Cart Item Updated")
            added = False
            updated = True
            # return redirect("carts:cart")
        else:
            cart_obj.combo_item.add(cart_item)
            print("Combo Added")
            added = True
            updated = False
            # return redirect("carts:cart")

        # print(combo_id)
        cartCount = cart_obj.get_cartItems()
        print(cartCount)
        if request.is_ajax():
            print("Ajax Request")
            json_data = {
            "added": added,
            # "not_added": not added,
            "updated": updated,
            # "not_updated": not updated
            "ItemCount": cartCount
            }
            return JsonResponse(json_data, status=200)
            # return JsonResponse("message: Error", status_code=400)

    return redirect("carts:cart")
</code>```

```<code>class ComboList(ListView):
    template_name = 'products/list.html'

    def get_context_data(self, *args, **kwargs):
        context = super(ComboList, self).get_context_data(*args, **kwargs)
        cart_obj, new_obj = Cart.objects.new_or_get(self.request)
        context['cart'] = cart_obj
        return context

    def get_queryset(self, *args, **kwargs):
        request = self.request
        combo = Combo.objects.all()
        return combo
</code>```

combo-update.html

```<code><form method="POST" action="{% url 'carts:combo_add_to_cart' %}" data-endpoint="{% url 'carts:combo_add_to_cart' %}" class="form add-ajax">
    {% csrf_token %}
    <input type="hidden" name="combo_id" value="{{ combo.id }}">
    <span class="submit-span">
        <button type="submit" class="btn btn-success">Add to Cart</button>
    </span>
</form>
</code>```

list.html

```<code>{% extends 'base.html' %}

{% block content %}
    <div class="container">
        <h1>Combos</h1>
        <hr>
        {% for obj in object_list %}
            <b style="font-size: 1.5em;">{{ obj.title }} | Regular Rs.{{ obj.combo_regular_price }} | Sale Rs.{{ obj.combo_sale_price }}</b>

            {% include "products/snippets/combo-update.html" with combo=obj %}

            <br>
        {% endfor %}
    </div>
{% endblock %}
</code>```

base.js

```<code>var comboForm = $(".add-ajax")

  comboForm.submit(function(event){
    event.preventDefault();

    var thisForm = $(this)
    var actionEndpoint = thisForm.attr("data-endpoint");
    var httpMethod = thisForm.attr("method");
    var formData = thisForm.serialize();

    $.ajax({
      url: actionEndpoint,
      method: httpMethod,
      data: formData,
      success: function(data){
        var submitSpan = thisForm.find(".submit-span")

        if(data.added){
          submitSpan.html('<button type="submit" class="btn btn-success">Add More?</button>')
          swal({
          title: "",
          text: "Added to cart!",
          icon: "success",
          button: "Okay",
        })
        }else{
          if(data.updated){
            submitSpan.html('<button type="submit" class="btn btn-success">Add More?</button>')
          }else{
            submitSpan.html('<button type="submit" class="btn btn-success">Add to Cart</button>')
          }
        }
        var cartCount = $(".cart-count")
        cartCount.text(data.ItemCount)
        console.log(data.ItemCount)
        if(window.location.href.indexOf('cart') != -1){
          refreshCart()
        }
      },
      error: function(errorData){
        swal({
          title: "Opps!",
          text: "An error occured!",
          icon: "error",
          button: "Okay",
        })

        console.log("No API")
        console.log("error", errorData)
      }
    })

  })
</code>```

Traceback

```<code>[01/Jun/2020 19:05:26] "POST /carts/cart/combo/add-to-cart/ HTTP/1.1" 302 0
[01/Jun/2020 19:05:26] "GET /accounts/login/?next=/carts/cart/combo/add-to-cart/ HTTP/1.1" 200 4146

</code>```

答:
It was because of the javascript that I wrote!

Firs in my cart views.py file I added

```<code>def combo_add_to_cart(request):
    combo_id = request.POST.get('combo_id')
    if not request.user.is_authenticated:
        if request.is_ajax():
            print("Ajax Request")
            json_data = {
            "noUser": True,
            }
            return JsonResponse(json_data, status=200)
    else:
        if combo_id is not None:
            try:
                combo_obj = Combo.objects.get(id=combo_id)
</code>```

In the ajax call of base.js I added a condition

```<code>        if(data.noUser){
          swal({
            title: "Opps! You are not logged in",
            text: "Redirecting......",
            button: false,
          })
          setTimeout(function(){
            window.location.href='/accounts/login/'
          }, 1000)
        }else{
          if(data.added){
            submitSpan.html('<button type="submit" class="btn btn-success">Add More?</button>')
            swal({
            title: "",
            text: "Added to cart!",
            icon: "success",
            button: "Okay",
          })
          }else{
            if(data.updated){
              submitSpan.html('<button type="submit" class="btn btn-success">Add More?</button>')
            }else{
              submitSpan.html('<button type="submit" class="btn btn-success">Add to Cart</button>')
            }
          }
        }
</code>```

So now it works even without the login_required decorator.

Body:
@login_required decorator not redirecting me to the login page

When I click the add to cart button it doesn't redirect me to the login page. It just doesn't do anything. I tried the login required decorator in another function. Like the home view action. And when I try to access the home page it directly redirects me to the login page. But in the combo_add_to_cart it doesn't seems to work. But I have found something in the terminal. I have seen that when I click the add to cart button it first sends a post request of "POST /carts/cart/combo/add-to-cart/ " then it sends a get request "GET /accounts/login/?next=/carts/cart/combo/add-to-cart/"

accounts views.py

class Login(FormView):
    form_class = LoginForm
    success_url = '/'
    template_name = 'accounts/login.html'

    def form_valid(self, form):
        request = self.request
        next_ = request.GET.get('next')
        next_post = request.POST.get('next')
        redirect_path = next_ or next_post or None
        email = form.cleaned_data.get('email')
        password = form.cleaned_data.get('password')
        user = authenticate(request, email=email, password=password)
        if user is not None:
            login(request, user)
            if is_safe_url(redirect_path, request.get_host()):
                return redirect(redirect_path)
            else:
                return redirect("/")
        return super(Login, self).form_invalid(form)

cart views.py

@login_required(login_url='/accounts/login/')
def combo_add_to_cart(request):
    combo_id = request.POST.get('combo_id')
    if combo_id is not None:
        try:
            combo_obj = Combo.objects.get(id=combo_id)
        except Combo.DoesNotExist:
            return("carts:cart")

        combo = combo_obj

        cart_item, created = ComboCartItem.objects.get_or_create(
            combo=combo,
            user=request.user,
            ordered=False
        )

        cart_obj, new_obj = Cart.objects.new_or_get(request)

        if cart_obj.combo_item.filter(combo__id=combo.id).exists():
            cart_item.quantity += 1
            cart_item.save()
            print("Cart Item Updated")
            added = False
            updated = True
            # return redirect("carts:cart")
        else:
            cart_obj.combo_item.add(cart_item)
            print("Combo Added")
            added = True
            updated = False
            # return redirect("carts:cart")

        # print(combo_id)
        cartCount = cart_obj.get_cartItems()
        print(cartCount)
        if request.is_ajax():
            print("Ajax Request")
            json_data = {
            "added": added,
            # "not_added": not added,
            "updated": updated,
            # "not_updated": not updated
            "ItemCount": cartCount
            }
            return JsonResponse(json_data, status=200)
            # return JsonResponse("message: Error", status_code=400)

    return redirect("carts:cart")

class ComboList(ListView):
    template_name = 'products/list.html'

    def get_context_data(self, *args, **kwargs):
        context = super(ComboList, self).get_context_data(*args, **kwargs)
        cart_obj, new_obj = Cart.objects.new_or_get(self.request)
        context['cart'] = cart_obj
        return context

    def get_queryset(self, *args, **kwargs):
        request = self.request
        combo = Combo.objects.all()
        return combo

combo-update.html

<form method="POST" action="{% url 'carts:combo_add_to_cart' %}" data-endpoint="{% url 'carts:combo_add_to_cart' %}" class="form add-ajax">
    {% csrf_token %}
    <input type="hidden" name="combo_id" value="{{ combo.id }}">

        <button type="submit" class="btn btn-success">Add to Cart</button>

</form>

list.html

{% extends 'base.html' %}

{% block content %}

Combos

        {% for obj in object_list %}
            {{ obj.title }} | Regular Rs.{{ obj.combo_regular_price }} | Sale Rs.{{ obj.combo_sale_price }}

            {% include "products/snippets/combo-update.html" with combo=obj %}

        {% endfor %}

{% endblock %}

base.js

var comboForm = $(".add-ajax")

  comboForm.submit(function(event){
    event.preventDefault();

    var thisForm = $(this)
    var actionEndpoint = thisForm.attr("data-endpoint");
    var httpMethod = thisForm.attr("method");
    var formData = thisForm.serialize();

    $.ajax({
      url: actionEndpoint,
      method: httpMethod,
      data: formData,
      success: function(data){
        var submitSpan = thisForm.find(".submit-span")

        if(data.added){
          submitSpan.html('<button type="submit" class="btn btn-success">Add More?</button>')
          swal({
          title: "",
          text: "Added to cart!",
          icon: "success",
          button: "Okay",
        })
        }else{
          if(data.updated){
            submitSpan.html('<button type="submit" class="btn btn-success">Add More?</button>')
          }else{
            submitSpan.html('<button type="submit" class="btn btn-success">Add to Cart</button>')
          }
        }
        var cartCount = $(".cart-count")
        cartCount.text(data.ItemCount)
        console.log(data.ItemCount)
        if(window.location.href.indexOf('cart') != -1){
          refreshCart()
        }
      },
      error: function(errorData){
        swal({
          title: "Opps!",
          text: "An error occured!",
          icon: "error",
          button: "Okay",
        })

        console.log("No API")
        console.log("error", errorData)
      }
    })

  })

Traceback

[01/Jun/2020 19:05:26] "POST /carts/cart/combo/add-to-cart/ HTTP/1.1" 302 0
[01/Jun/2020 19:05:26] "GET /accounts/login/?next=/carts/cart/combo/add-to-cart/ HTTP/1.1" 200 4146

Body:
It was because of the javascript that I wrote!

Firs in my cart views.py file I added

def combo_add_to_cart(request):
    combo_id = request.POST.get('combo_id')
    if not request.user.is_authenticated:
        if request.is_ajax():
            print("Ajax Request")
            json_data = {
            "noUser": True,
            }
            return JsonResponse(json_data, status=200)
    else:
        if combo_id is not None:
            try:
                combo_obj = Combo.objects.get(id=combo_id)

In the ajax call of base.js I added a condition

        if(data.noUser){
          swal({
            title: "Opps! You are not logged in",
            text: "Redirecting......",
            button: false,
          })
          setTimeout(function(){
            window.location.href='/accounts/login/'
          }, 1000)
        }else{
          if(data.added){
            submitSpan.html('<button type="submit" class="btn btn-success">Add More?</button>')
            swal({
            title: "",
            text: "Added to cart!",
            icon: "success",
            button: "Okay",
          })
          }else{
            if(data.updated){
              submitSpan.html('<button type="submit" class="btn btn-success">Add More?</button>')
            }else{
              submitSpan.html('<button type="submit" class="btn btn-success">Add to Cart</button>')
            }
          }
        }

So now it works even without the login_required decorator.