问:
Reading in from a file with getline() having multiple info on one line get invalid argument error
hello folks im still a beginner to c++ so i apologize in advance.
okay so some context is this is a hw assignment for my class we have to make a an array that holds all the books that are being read in from the a txt file then organize them by hashing. the part that im stuck on is reading in the data i cant seem to get it right. the error occurs in load table function, it reads the first line and i put the cout stuff under it to test it out and it does print the first book out but after it throws a invalid argument error.

Input file:

```<code>116807#A Tale of Two Cities#Charles Dickens#3.73#9.99#1
111272#The Iliad#Homer#2.78#9.99#10
164440#The Great Gatsby#F. Scott Fitzgerald#4.92#9.99#8
122503#Pride and Prejudice#Jane Austen#3.29#8.99#3
144303#Little Lord Fauntleroy#Frances Hodgson Burnett#3.09#9.99#1
170933#Alice's Adventures in Wonderland#Lewis Carroll#2.78#9.99#6
199097#The Awakening#Kate Chopin#4.12#8.99#1
177633#Robinson Crusoe#Daniel Defoe#3.49#7.99#2
111967#Little Women#Louisa May Alcott#4.93#7.99#6
191745#Emma#Jane Austen#4.91#7.99#8
135001#Sense and Sensibility#Jane Austen#4.08#8.99#9
171490#The Wonderful Wizard of Oz#L. Frank Baum#2.96#7.99#4
127722#Lorna Doone#R. D. Blackmore#3.49#9.99#2
106853#Jane Eyre#Charlotte Brontë#2.08#7.99#4
160298#Wuthering Heights#Emily Brontë#3.35#8.99#6
189814#The Secret Garden#Frances Hodgson Burnett#4.36#9.99#10
124115#Tales from the Arabian Nights#Richard Francis Burton#3.29#8.99#8
134195#Through the Looking-Glass#Lewis Carroll#2.04#7.99#9
182188#Don Quixote of La Mancha#Miguel de Cervantes Saavedra#4.05#8.99#3
131566#The Man Who Was Thursday#G.K. Chesterton#3.37#9.99#5
151501#The Napoleon of Notting Hill#G.K. Chesterton#2.71#9.99#8
119358#The Moonstone#Wilkie Collins#3.97#7.99#5
121609#The Woman in White#Wilkie Collins#4.45#7.99#6
166298#Heart of Darkness#Joseph Conrad#3.99#9.99#3
100260#Lord Jim#Joseph Conrad#3.94#8.99#6
125968#The Deerslayer#James Fenimore Cooper#4.3#8.99#3
197942#The Last of the Mohicans#James Fenimore Cooper#3.82#8.99#8
133821#The Red Badge of Courage#Stephen Crane#2.12#7.99#2
148590#The Fortunes and Misfortunes#Defoe#2.38#7.99#7
119790#Bleak House#Charles Dickens#4.79#9.99#7
197972#A Christmas Carol#Charles Dickens#3.95#7.99#5
145223#David Copperfield#Charles Dickens#3.6#8.99#7
136123#Great Expectations#Charles Dickens#4.13#9.99#9
129094#Oliver Twist#Charles Dickens#2.44#8.99#5
125226#The Brothers Karamazov#Fyodor Dostoyevsky#2.63#7.99#5
159590#Crime and Punishment#Fyodor Dostoyevsky#4.59#8.99#8
197385#The Adventures of Sherlock Holmes#Arthur Conan Doyle#3.72#7.99#8
142385#The Hound of the Baskervilles#Arthur Conan Doyle#3.85#8.99#1
128144#The Count of Monte Cristo#Alexandre Dumas#4.35#7.99#6
163534#The Man in the Iron Mask#Alexandre Dumas#3.11#7.99#3
175244#Middlemarch#George Eliot#3.18#9.99#3
101815#Silas Marner#George Eliot#3.33#9.99#8
189553#The Diary of a Nobody#George Grossmith and Weedon Grossmith#3.25#9.99#3
130211#Allan Quatermain#Henry Rider Haggard#2.77#8.99#6
137335#King Solomon's Mines#Henry Rider Haggard#4.95#7.99#8
197439#Far from the Madding Crowd#Thomas Hardy#3.31#7.99#2
168872#Tess of the D'Urbervilles#Thomas Hardy#4.94#8.99#6
139789#The Scarlet Letter#Nathaniel Hawthorne#3.15#8.99#10
115680#Tanglewood Tales for Girls and Boys#Nathaniel Hawthorne#3.55#7.99#4
133502#A Wonder-Book for Girls and Boys#Nathaniel Hawthorne#4.08#7.99#2
177844#The Four Million#O. Henry#4.08#9.99#2
154849#The Odyssey#Homer#2.31#7.99#5
195419#The Prisoner of Zenda#Anthony Hope#3.09#7.99#10
195223#The Hunchback of Notre-Dame#Victor Hugo#3.6#7.99#6
147317#Les Misérables#Victor Hugo#2#9.99#5
160597#The Sketch Book of Geoffrey Crayon#Washington Irving#2.04#9.99#1
141976#The Aspern Papers#Henry James#4.54#7.99#5
148381#The Turn of the Screw#Henry James#3.65#9.99#10
178209#The Jungle Book#Rudyard Kipling#3.53#8.99#8
164607#Kim#Rudyard Kipling#4.22#7.99#7
170053#The Man Who Would Be King#Rudyard Kipling#3.3#9.99#1
160444#The Phantom of the Opera#Gaston Leroux#4.85#8.99#9
108155#The Call of the Wild#Jack London#2.57#9.99#9
158266#White Fang#Jack London#4.11#9.99#5
174819#The Princess and Curdie#George MacDonald#2.33#9.99#1
148762#The Princess and the Goblin#George MacDonald#3.97#7.99#9
160589#The Prince#Niccolò Machiavelli#2.77#8.99#9
161200#Moby Dick#Herman Melville#3.6#8.99#8
145480#Utopia#Thomas More#3.55#7.99#8
141238#Rights of Man#Thomas Paine#2.26#8.99#8
161113#Tales of Mystery & Imagination#Edgar Allan Poe#4.93#9.99#5
168418#Ivanhoe#Sir Walter Scott#2.85#7.99#6
176563#Waverley#Sir Walter Scott#2.17#8.99#10
162967#Black Beauty#Anna Sewell#2.69#7.99#4
104473#Hamlet#William Shakespeare#2.48#8.99#9
163459#King Lear#William Shakespeare#2.3#9.99#3
100973#MacBeth#William Shakespeare#3.97#8.99#1
135231#A Midsummer Night's Dream#Shakespeare#3.03#9.99#1
162533#Othello, The Moor of Venice#Shakespeare#4.03#9.99#1
123934#Romeo and Juliet#hakespeare#4.79#9.99#5
133549#The Taming of the Shrew#Shakespeare#3.49#9.99#1
115879#The Tempest#William Shakespeare#3.7#7.99#4
173650#Frankenstein#Mary Shelley#3.29#9.99#7
110299#The Strange Case of Dr. Jekyll and Mr. Hyde#Robert#2.21#9.99#5
168244#Kidnapped#Robert Louis Stevenson#4.96#7.99#5
191560#Dracula#Bram Stoker#4.51#9.99#4
189551#Uncle Tom's Cabin#Harriet Beecher Stowe#2.05#7.99#9
159274#Gulliver's Travels#Jonathan Swift#4.13#9.99#6
122012#Vanity Fair#William Makepeace Thackeray#2.88#9.99#9
181550#Walden#Henry David Thoreau#2.95#8.99#2
135690#Anna Karenina#Leo Tolstoy#2.1#9.99#4
109565#War and Peace#Leo Tolstoy#4.42#9.99#3
107307#Barchester Towers#Anthony Trollope#2.1#9.99#10
143127#The Adventures of Huckleberry Finn#Twain#4.87#9.99#6
116641#The Adventures of Tom Sawyer#twain#2.48#9.99#6
115974#A Connecticut Yankee in King Arthur's Court#Twain#4.73#9.99#2
109239#Journey to the Center of the Earth#Jules Verne#3.05#8.99#4
154189#20,000 Leagues Under the Sea#Jules Verne#3.56#8.99#1
145898#The Time Machine#H.G. Wells#3.2#7.99#1
198867#The Age of Innocence#Edith Wharton#2.39#9.99#2
160811#The Importance of Being Earnest#Oscar Wilde#4.91#8.99#9
126671#The Picture of Dorian Gray#Oscar Wilde#4.45#7.99#1
</code>```

Program:

```<code>#include <iostream>
#include <string>
#include <fstream>

using namespace std;

struct book
{
    int bookid;
    string title;
    string author;
    float cost;
    float price;
    int quantity;
};

int getHashKey(int, int);
void clearTable(book[], int);
void loadTable(book[], int);
void loadBook(book[], book, int);

int main()
{
    int  size;
    cout << "Enter size of table!" << endl;
    cin >> size;
    book * arr = new book[size];

    clearTable(arr, size);
    loadTable(arr, size);
    /*for (int i = 0; i < size; i++)
    {
        cout << arr[i].bookid << endl;
    }*/

    delete[] arr;
    return 0;
}
int getHashKey(int key, int max_size)
{
    return key % max_size;
}
void clearTable(book arr[], int size)
{
    for (int i = 0; i < size; i++)
    {
        arr[i].bookid = -1;
    }
}
void loadBook(book arr[], book val, int size)
{
    int key = (val.bookid % size);
    while (arr[key].bookid != -1)
    {
        key = (key + 1) % size;
    }
    arr[key] = val;
}

void loadTable(book arr[], int size)
{
    book tempBook;
    string line;
    char s;
    ifstream myfile;
    myfile.open("inventory.txt");
    if (myfile.is_open())
    {
        while (!myfile.eof())
        {
            //this is the part that reads in the line stopping at the #
            //it reads the first line correct than it throws a invalid
            //argument error.
            getline(myfile, line, '#');
            tempBook.bookid = stoi(line);

            getline(myfile, line, '#');
            tempBook.title = line;

            getline(myfile, line, '#');
            tempBook.author = line;

            getline(myfile, line, '#');
            tempBook.cost = stof(line);

            getline(myfile, line, '#');
            tempBook.price = stof(line);

            getline(myfile, line, '#');
            tempBook.quantity = stoi(line);

            cout << tempBook.bookid << endl;
            cout << tempBook.title << endl;
            cout << tempBook.author << endl;
            cout << tempBook.cost << endl;
            cout << tempBook.price << endl;
            cout << tempBook.quantity << endl;

            //add load book

            //loadBook(arr, tempBook, size);

        }
    }

}
</code>```

答:
The error on the 2nd line happens because the last field of the row doesn't have # after it. So the last getline() should use '\n' as the delimiter, not '#'.

When this is fixe, you get an error is happening after reading the last line, because you're using while (!myfile.eof()). The EOF condition isn't set until after you try to read the file at the end, as explained in Why is iostream::eof inside a loop condition considered wrong?. So it's reading an empty line, then trying to parse it as a number. You should put the first getline() call in the while() condition.

The corrected program is:

```<code>#include <iostream>
#include <string>
#include <fstream>

using namespace std;

struct book
{
    int bookid;
    string title;
    string author;
    float cost;
    float price;
    int quantity;
};

int getHashKey(int, int);
void clearTable(book[], int);
void loadTable(book[], int);
void loadBook(book[], book, int);

int main()
{
    int  size;
    cout << "Enter size of table!" << endl;
    cin >> size;
    book * arr = new book[size];

    clearTable(arr, size);
    loadTable(arr, size);
    /*for (int i = 0; i < size; i++)
    {
        cout << arr[i].bookid << endl;
    }*/

    delete[] arr;
    return 0;
}
int getHashKey(int key, int max_size)
{
    return key % max_size;
}
void clearTable(book arr[], int size)
{
    for (int i = 0; i < size; i++)
    {
        arr[i].bookid = -1;
    }
}
void loadBook(book arr[], book val, int size)
{
    int key = (val.bookid % size);
    while (arr[key].bookid != -1)
    {
        key = (key + 1) % size;
    }
    arr[key] = val;
}

void loadTable(book arr[], int size)
{
    book tempBook;
    string line;
    char s;
    ifstream myfile;
    myfile.open("inventory.txt");
    if (myfile.is_open())
    {
        while (getline(myfile, line, '#'))
        {
            tempBook.bookid = stoi(line);

            getline(myfile, line, '#');
            tempBook.title = line;

            getline(myfile, line, '#');
            tempBook.author = line;

            getline(myfile, line, '#');
            tempBook.cost = stof(line);

            getline(myfile, line, '#');
            tempBook.price = stof(line);

            getline(myfile, line, '\n');
            tempBook.quantity = stoi(line);

            cout << tempBook.bookid << endl;
            cout << tempBook.title << endl;
            cout << tempBook.author << endl;
            cout << tempBook.cost << endl;
            cout << tempBook.price << endl;
            cout << tempBook.quantity << endl;

            //add load book

            //loadBook(arr, tempBook, size);

        }
    }
}
</code>```

Body:
hello folks im still a beginner to c++ so i apologize in advance.
okay so some context is this is a hw assignment for my class we have to make a an array that holds all the books that are being read in from the a txt file then organize them by hashing. the part that im stuck on is reading in the data i cant seem to get it right. the error occurs in load table function, it reads the first line and i put the cout stuff under it to test it out and it does print the first book out but after it throws a invalid argument error.

Input file:

116807#A Tale of Two Cities#Charles Dickens#3.73#9.99#1
111272#The Iliad#Homer#2.78#9.99#10
164440#The Great Gatsby#F. Scott Fitzgerald#4.92#9.99#8
122503#Pride and Prejudice#Jane Austen#3.29#8.99#3
144303#Little Lord Fauntleroy#Frances Hodgson Burnett#3.09#9.99#1
170933#Alice's Adventures in Wonderland#Lewis Carroll#2.78#9.99#6
199097#The Awakening#Kate Chopin#4.12#8.99#1
177633#Robinson Crusoe#Daniel Defoe#3.49#7.99#2
111967#Little Women#Louisa May Alcott#4.93#7.99#6
191745#Emma#Jane Austen#4.91#7.99#8
135001#Sense and Sensibility#Jane Austen#4.08#8.99#9
171490#The Wonderful Wizard of Oz#L. Frank Baum#2.96#7.99#4
127722#Lorna Doone#R. D. Blackmore#3.49#9.99#2
106853#Jane Eyre#Charlotte Brontë#2.08#7.99#4
160298#Wuthering Heights#Emily Brontë#3.35#8.99#6
189814#The Secret Garden#Frances Hodgson Burnett#4.36#9.99#10
124115#Tales from the Arabian Nights#Richard Francis Burton#3.29#8.99#8
134195#Through the Looking-Glass#Lewis Carroll#2.04#7.99#9
182188#Don Quixote of La Mancha#Miguel de Cervantes Saavedra#4.05#8.99#3
131566#The Man Who Was Thursday#G.K. Chesterton#3.37#9.99#5
151501#The Napoleon of Notting Hill#G.K. Chesterton#2.71#9.99#8
119358#The Moonstone#Wilkie Collins#3.97#7.99#5
121609#The Woman in White#Wilkie Collins#4.45#7.99#6
166298#Heart of Darkness#Joseph Conrad#3.99#9.99#3
100260#Lord Jim#Joseph Conrad#3.94#8.99#6
125968#The Deerslayer#James Fenimore Cooper#4.3#8.99#3
197942#The Last of the Mohicans#James Fenimore Cooper#3.82#8.99#8
133821#The Red Badge of Courage#Stephen Crane#2.12#7.99#2
148590#The Fortunes and Misfortunes#Defoe#2.38#7.99#7
119790#Bleak House#Charles Dickens#4.79#9.99#7
197972#A Christmas Carol#Charles Dickens#3.95#7.99#5
145223#David Copperfield#Charles Dickens#3.6#8.99#7
136123#Great Expectations#Charles Dickens#4.13#9.99#9
129094#Oliver Twist#Charles Dickens#2.44#8.99#5
125226#The Brothers Karamazov#Fyodor Dostoyevsky#2.63#7.99#5
159590#Crime and Punishment#Fyodor Dostoyevsky#4.59#8.99#8
197385#The Adventures of Sherlock Holmes#Arthur Conan Doyle#3.72#7.99#8
142385#The Hound of the Baskervilles#Arthur Conan Doyle#3.85#8.99#1
128144#The Count of Monte Cristo#Alexandre Dumas#4.35#7.99#6
163534#The Man in the Iron Mask#Alexandre Dumas#3.11#7.99#3
175244#Middlemarch#George Eliot#3.18#9.99#3
101815#Silas Marner#George Eliot#3.33#9.99#8
189553#The Diary of a Nobody#George Grossmith and Weedon Grossmith#3.25#9.99#3
130211#Allan Quatermain#Henry Rider Haggard#2.77#8.99#6
137335#King Solomon's Mines#Henry Rider Haggard#4.95#7.99#8
197439#Far from the Madding Crowd#Thomas Hardy#3.31#7.99#2
168872#Tess of the D'Urbervilles#Thomas Hardy#4.94#8.99#6
139789#The Scarlet Letter#Nathaniel Hawthorne#3.15#8.99#10
115680#Tanglewood Tales for Girls and Boys#Nathaniel Hawthorne#3.55#7.99#4
133502#A Wonder-Book for Girls and Boys#Nathaniel Hawthorne#4.08#7.99#2
177844#The Four Million#O. Henry#4.08#9.99#2
154849#The Odyssey#Homer#2.31#7.99#5
195419#The Prisoner of Zenda#Anthony Hope#3.09#7.99#10
195223#The Hunchback of Notre-Dame#Victor Hugo#3.6#7.99#6
147317#Les Misérables#Victor Hugo#2#9.99#5
160597#The Sketch Book of Geoffrey Crayon#Washington Irving#2.04#9.99#1
141976#The Aspern Papers#Henry James#4.54#7.99#5
148381#The Turn of the Screw#Henry James#3.65#9.99#10
178209#The Jungle Book#Rudyard Kipling#3.53#8.99#8
164607#Kim#Rudyard Kipling#4.22#7.99#7
170053#The Man Who Would Be King#Rudyard Kipling#3.3#9.99#1
160444#The Phantom of the Opera#Gaston Leroux#4.85#8.99#9
108155#The Call of the Wild#Jack London#2.57#9.99#9
158266#White Fang#Jack London#4.11#9.99#5
174819#The Princess and Curdie#George MacDonald#2.33#9.99#1
148762#The Princess and the Goblin#George MacDonald#3.97#7.99#9
160589#The Prince#Niccolò Machiavelli#2.77#8.99#9
161200#Moby Dick#Herman Melville#3.6#8.99#8
145480#Utopia#Thomas More#3.55#7.99#8
141238#Rights of Man#Thomas Paine#2.26#8.99#8
161113#Tales of Mystery & Imagination#Edgar Allan Poe#4.93#9.99#5
168418#Ivanhoe#Sir Walter Scott#2.85#7.99#6
176563#Waverley#Sir Walter Scott#2.17#8.99#10
162967#Black Beauty#Anna Sewell#2.69#7.99#4
104473#Hamlet#William Shakespeare#2.48#8.99#9
163459#King Lear#William Shakespeare#2.3#9.99#3
100973#MacBeth#William Shakespeare#3.97#8.99#1
135231#A Midsummer Night's Dream#Shakespeare#3.03#9.99#1
162533#Othello, The Moor of Venice#Shakespeare#4.03#9.99#1
123934#Romeo and Juliet#hakespeare#4.79#9.99#5
133549#The Taming of the Shrew#Shakespeare#3.49#9.99#1
115879#The Tempest#William Shakespeare#3.7#7.99#4
173650#Frankenstein#Mary Shelley#3.29#9.99#7
110299#The Strange Case of Dr. Jekyll and Mr. Hyde#Robert#2.21#9.99#5
168244#Kidnapped#Robert Louis Stevenson#4.96#7.99#5
191560#Dracula#Bram Stoker#4.51#9.99#4
189551#Uncle Tom's Cabin#Harriet Beecher Stowe#2.05#7.99#9
159274#Gulliver's Travels#Jonathan Swift#4.13#9.99#6
122012#Vanity Fair#William Makepeace Thackeray#2.88#9.99#9
181550#Walden#Henry David Thoreau#2.95#8.99#2
135690#Anna Karenina#Leo Tolstoy#2.1#9.99#4
109565#War and Peace#Leo Tolstoy#4.42#9.99#3
107307#Barchester Towers#Anthony Trollope#2.1#9.99#10
143127#The Adventures of Huckleberry Finn#Twain#4.87#9.99#6
116641#The Adventures of Tom Sawyer#twain#2.48#9.99#6
115974#A Connecticut Yankee in King Arthur's Court#Twain#4.73#9.99#2
109239#Journey to the Center of the Earth#Jules Verne#3.05#8.99#4
154189#20,000 Leagues Under the Sea#Jules Verne#3.56#8.99#1
145898#The Time Machine#H.G. Wells#3.2#7.99#1
198867#The Age of Innocence#Edith Wharton#2.39#9.99#2
160811#The Importance of Being Earnest#Oscar Wilde#4.91#8.99#9
126671#The Picture of Dorian Gray#Oscar Wilde#4.45#7.99#1

Program:

#include <iostream>
#include <string>
#include <fstream>

using namespace std;

struct book
{
    int bookid;
    string title;
    string author;
    float cost;
    float price;
    int quantity;
};

int getHashKey(int, int);
void clearTable(book[], int);
void loadTable(book[], int);
void loadBook(book[], book, int);

int main()
{
    int  size;
    cout << "Enter size of table!" << endl;
    cin >> size;
    book * arr = new book[size];

    clearTable(arr, size);
    loadTable(arr, size);
    /*for (int i = 0; i < size; i++)
    {
        cout << arr[i].bookid << endl;
    }*/

    delete[] arr;
    return 0;
}
int getHashKey(int key, int max_size)
{
    return key % max_size;
}
void clearTable(book arr[], int size)
{
    for (int i = 0; i < size; i++)
    {
        arr[i].bookid = -1;
    }
}
void loadBook(book arr[], book val, int size)
{
    int key = (val.bookid % size);
    while (arr[key].bookid != -1)
    {
        key = (key + 1) % size;
    }
    arr[key] = val;
}

void loadTable(book arr[], int size)
{
    book tempBook;
    string line;
    char s;
    ifstream myfile;
    myfile.open("inventory.txt");
    if (myfile.is_open())
    {
        while (!myfile.eof())
        {
            //this is the part that reads in the line stopping at the #
            //it reads the first line correct than it throws a invalid
            //argument error.
            getline(myfile, line, '#');
            tempBook.bookid = stoi(line);

            getline(myfile, line, '#');
            tempBook.title = line;

            getline(myfile, line, '#');
            tempBook.author = line;

            getline(myfile, line, '#');
            tempBook.cost = stof(line);

            getline(myfile, line, '#');
            tempBook.price = stof(line);

            getline(myfile, line, '#');
            tempBook.quantity = stoi(line);

            cout << tempBook.bookid << endl;
            cout << tempBook.title << endl;
            cout << tempBook.author << endl;
            cout << tempBook.cost << endl;
            cout << tempBook.price << endl;
            cout << tempBook.quantity << endl;

            //add load book

            //loadBook(arr, tempBook, size);

        }
    }

}

Body:
The error on the 2nd line happens because the last field of the row doesn't have # after it. So the last getline() should use '\n' as the delimiter, not '#'.

When this is fixe, you get an error is happening after reading the last line, because you're using while (!myfile.eof()). The EOF condition isn't set until after you try to read the file at the end, as explained in Why is iostream::eof inside a loop condition considered wrong?. So it's reading an empty line, then trying to parse it as a number. You should put the first getline() call in the while() condition.

The corrected program is:

#include <iostream>
#include <string>
#include <fstream>

using namespace std;

struct book
{
    int bookid;
    string title;
    string author;
    float cost;
    float price;
    int quantity;
};

int getHashKey(int, int);
void clearTable(book[], int);
void loadTable(book[], int);
void loadBook(book[], book, int);

int main()
{
    int  size;
    cout << "Enter size of table!" << endl;
    cin >> size;
    book * arr = new book[size];

    clearTable(arr, size);
    loadTable(arr, size);
    /*for (int i = 0; i < size; i++)
    {
        cout << arr[i].bookid << endl;
    }*/

    delete[] arr;
    return 0;
}
int getHashKey(int key, int max_size)
{
    return key % max_size;
}
void clearTable(book arr[], int size)
{
    for (int i = 0; i < size; i++)
    {
        arr[i].bookid = -1;
    }
}
void loadBook(book arr[], book val, int size)
{
    int key = (val.bookid % size);
    while (arr[key].bookid != -1)
    {
        key = (key + 1) % size;
    }
    arr[key] = val;
}

void loadTable(book arr[], int size)
{
    book tempBook;
    string line;
    char s;
    ifstream myfile;
    myfile.open("inventory.txt");
    if (myfile.is_open())
    {
        while (getline(myfile, line, '#'))
        {
            tempBook.bookid = stoi(line);

            getline(myfile, line, '#');
            tempBook.title = line;

            getline(myfile, line, '#');
            tempBook.author = line;

            getline(myfile, line, '#');
            tempBook.cost = stof(line);

            getline(myfile, line, '#');
            tempBook.price = stof(line);

            getline(myfile, line, '\n');
            tempBook.quantity = stoi(line);

            cout << tempBook.bookid << endl;
            cout << tempBook.title << endl;
            cout << tempBook.author << endl;
            cout << tempBook.cost << endl;
            cout << tempBook.price << endl;
            cout << tempBook.quantity << endl;

            //add load book

            //loadBook(arr, tempBook, size);

        }
    }
}


来源: stackexchange

问:
Unable to cast object of generic type to generic interface C#
I have two interfaces:

```<code>public interface IDbModel {}
public interface IDmModel {}
</code>```

And classes derived from this:

```<code>public class DbModel : IDbModel {}
public class DmModel : IDmModel {}
public class Middle { }
</code>```

Also I have two interfaces with restrictions:

```<code>public interface IRule { }
public interface IRule<in TInput, out TOutput> : IRule
    where TInput : IDmModel
    where TOutput : IDbModel
{
    TOutput Apply(TInput elem);
}
</code>```

And one abstract class derived from this interface:

```<code>public abstract class Rule<TDmModel, TMiddle, TDb> : IRule<TDmModel, TDb>
    where TDmModel : IDmModel
    where TDb : IDbModel
{
    private readonly Func<TDmModel, TMiddle> _rule;
    protected Rule(Func<TDmModel, TMiddle> rule) { _rule = rule; }
    protected abstract TDb Apply(TMiddle transformedMessage);
    public TDb Apply(TDmModel elem) { ... }
}
</code>```

After this I created two classes derived from this abstract class:

```<code>public class RuleA : Rule<DmModel, Middle, DbModel>
{
    public RuleA(Func<DmModel, Middle> rule) : base(rule) {}
    protected override DbMode Apply(Middle transformedMessage) { ... }
}

public class RuleB : RuleA
{
    public RuleB() : base((dm) => new Middle()) {}
}
</code>```

RuleB : RuleA : Rule< DmModel,Middle,DbModel > : IRule< IDmModel,IDbModel > : IRule

And when I try to cast object of RuleB to IRule<IDmModel, IDbModel> occours unhandled exception

Unable to cast object of type 'ParsreCombinators.RuleB' to type 'ParsreCombinators.IRule`2[ParsreCombinators.IDmModel,ParsreCombinators.IDbModel]'.

```<code>var ruleB = (IRule<IDmModel, IDbModel>)new RuleB(); // Exception
IDbModel dbModel = ruleB.Apply(new DmModel());
</code>```

What wrong with this

To make the example less confusing I simplify it:

EDIT:

After the answers I understood, what is the problem and to make the example less confusing I simplify it:

```<code>public interface IDbModel {}
public interface IDmModel {}

public class DbModel : IDbModel {}
public class DmModel : IDmModel {}

public interface IRule<in TInput, out TOutput>
    where TInput : IDmModel
    where TOutput : IDbModel
{
    TOutput Apply(TInput elem);
}

public class RuleA : IRule<DmModel, DbModel>
{
    public DbModel Apply(DmModel elem) { ... }
}

var ruleA = (IRule<IDmModel, IDbModel>)new RuleA(); // Exception
</code>```

答:
This is a pretty confusing example, but I believe the problem is you're casting to a generic type and giving it interfaces, when the classes your deriving from are forcing you to use DmModel and DbMode.

Perhaps this is what you meant:

```<code>var ruleB = (IRule<DmModel, DbMode>)new RuleB();
</code>```

That compiles just fine, and I with that way your classes are structured, is the only option other than restructuring.

ContentLicense: CC BY-SA 3.0

Body:
I have two interfaces:

public interface IDbModel {}
public interface IDmModel {}

And classes derived from this:

public class DbModel : IDbModel {}
public class DmModel : IDmModel {}
public class Middle { }

Also I have two interfaces with restrictions:

public interface IRule { }
public interface IRule<in TInput, out TOutput> : IRule
    where TInput : IDmModel
    where TOutput : IDbModel
{
    TOutput Apply(TInput elem);
}

And one abstract class derived from this interface:

public abstract class Rule<TDmModel, TMiddle, TDb> : IRule<TDmModel, TDb>
    where TDmModel : IDmModel
    where TDb : IDbModel
{
    private readonly Func<TDmModel, TMiddle> _rule;
    protected Rule(Func<TDmModel, TMiddle> rule) { _rule = rule; }
    protected abstract TDb Apply(TMiddle transformedMessage);
    public TDb Apply(TDmModel elem) { ... }
}

After this I created two classes derived from this abstract class:

public class RuleA : Rule<DmModel, Middle, DbModel>
{
    public RuleA(Func<DmModel, Middle> rule) : base(rule) {}
    protected override DbMode Apply(Middle transformedMessage) { ... }
}

public class RuleB : RuleA
{
    public RuleB() : base((dm) => new Middle()) {}
}

RuleB : RuleA : Rule< DmModel,Middle,DbModel > : IRule< IDmModel,IDbModel > : IRule

And when I try to cast object of RuleB to IRule<IDmModel, IDbModel> occours unhandled exception

Unable to cast object of type 'ParsreCombinators.RuleB' to type 'ParsreCombinators.IRule`2[ParsreCombinators.IDmModel,ParsreCombinators.IDbModel]'.

var ruleB = (IRule<IDmModel, IDbModel>)new RuleB(); // Exception
IDbModel dbModel = ruleB.Apply(new DmModel());

What wrong with this

To make the example less confusing I simplify it:

EDIT:

After the answers I understood, what is the problem and to make the example less confusing I simplify it:

public interface IDbModel {}
public interface IDmModel {}

public class DbModel : IDbModel {}
public class DmModel : IDmModel {}

public interface IRule<in TInput, out TOutput>
    where TInput : IDmModel
    where TOutput : IDbModel
{
    TOutput Apply(TInput elem);
}

public class RuleA : IRule<DmModel, DbModel>
{
    public DbModel Apply(DmModel elem) { ... }
}

var ruleA = (IRule<IDmModel, IDbModel>)new RuleA(); // Exception

Body:
This is a pretty confusing example, but I believe the problem is you're casting to a generic type and giving it interfaces, when the classes your deriving from are forcing you to use DmModel and DbMode.

Perhaps this is what you meant:

var ruleB = (IRule<DmModel, DbMode>)new RuleB();

That compiles just fine, and I with that way your classes are structured, is the only option other than restructuring.


问:
Unable to login at Github from Chrome/Chromium
I can login on my Github account from Firefox as normal. But when I try to log on in Chrome, I got the following error:

Happens on Windows and Ubuntu. What can I do?

[EDIT, UPDATE]

Here I left a screenshot of the console:

Not only happens on my account.

答: Disable Referer control plugin. that should fix the issue !</p>


问:
cross-browser 'getElementsByTagName' with namespace from responseXML
Am trying to read an XML response using getElementsByTagName:

```<code>var rows = items.responseXML.getElementsByTagName("z:row");

for (var i=0; i<rows.length; i++)
{
//do something
}
</code>```

Above code works fine in Firefox and IE but in chrome it throws null.. i mean it does not get any data.. when i alert the rows.length it gives me 0 always in chrome.

Then i searched in google and understood the issue is with xsd:element, then i changed "z:row" to only "row". Then it worked in Chrome but Firefox and IE returned 0 for rows.length.

Is there any method which across all browsers?

答:
If you don't care about the namespace then you could use the following:

```<code>xml.getElementsByTagNameNS("*", "yourElementHere")
</code>```

This will fetch any element with the desired name regardless of which namespace it has or whether it has any namespace at all. Additionally, this should work as expected across different browsers.

See link for documentation.

Body:
Am trying to read an XML response using getElementsByTagName:

var rows = items.responseXML.getElementsByTagName("z:row");

for (var i=0; i<rows.length; i++)
{
//do something
}

Above code works fine in Firefox and IE but in chrome it throws null.. i mean it does not get any data.. when i alert the rows.length it gives me 0 always in chrome.

Then i searched in google and understood the issue is with xsd:element, then i changed "z:row" to only "row". Then it worked in Chrome but Firefox and IE returned 0 for rows.length.

Is there any method which across all browsers?

Body:
If you don't care about the namespace then you could use the following:

xml.getElementsByTagNameNS("*", "yourElementHere")

This will fetch any element with the desired name regardless of which namespace it has or whether it has any namespace at all. Additionally, this should work as expected across different browsers.

See link for documentation.


问:
Screen resolution changes for the remote machine after safely closing the RDP session with "SupressWhenMinimzed"
First of all sorry for the (maybe not so specific) title as it consists of multiple topics.

The issue atm i'm having is related to my test automation setup. It consists of a linux machine handling the BE + FE and starting of the test themselves. And a Windows Server 2008 (Terminal) to which i connect through RDP session and it's the place the actual tests are run. For automation purposes i use Ranorex.

First of all how i have the Win machine set up:
As Ranorex is a GUI test automation tool it needs to have the components visible for the AUT (application under test) and for this reason you need to close the RPD client without closing the session itself otherwise the test will start failing.

For this i created a bat file with the following code:

```<code>%windir%\System32\tscon.exe RDP-Tcp#0 /dest:console
</code>```

And added a reg entry DWORD value under HKEY_LOCAL_MACHINE\Software\Microsoft\Terminal Server Client

```<code>RemoteDesktop_SuppressWhenMinimized
</code>```

with the value 2.

What this does is after running the bat file with admin rights it will close the RDP session but will still keep the terminal connection open to the Win Server machine allowing the tests to be run.

Now the issue on hand is that after closing the session safely the resolution that gets set for the left open session is 1024x768 while when RDP connection is open it is 1920x1200.

So finally the question which i haven't been able to answer myself: is it somehow possible to specify the resolution for the session that is kept open?

答:
I had to deal with the similar issue. I resolved it by installing Dameware MiniRemote Control agent in the machine. Once you connect to it via Dameware Mini Remote Control application you can change the resolution which you can't in RDP. (RealVNC or similar ones might work as others suggested, I didn't try them)

Some solutions which didn't work for me

QRes.exe /x:1920 /y:1200  http://qres.sourceforge.net/

Windows Management Instrumentation (in-built) : wmic desktopmonitor create screenheight=1920, screenwidth=1200

ChangeScreenResolution : http://tools.taubenkorb.at/change-screen-resolution/

Persistent windows: http://www.ninjacrab.com/persistent-windows/

Body:
First of all sorry for the (maybe not so specific) title as it consists of multiple topics.

The issue atm i'm having is related to my test automation setup. It consists of a linux machine handling the BE + FE and starting of the test themselves. And a Windows Server 2008 (Terminal) to which i connect through RDP session and it's the place the actual tests are run. For automation purposes i use Ranorex.

First of all how i have the Win machine set up:
As Ranorex is a GUI test automation tool it needs to have the components visible for the AUT (application under test) and for this reason you need to close the RPD client without closing the session itself otherwise the test will start failing.

For this i created a bat file with the following code:

%windir%\System32\tscon.exe RDP-Tcp#0 /dest:console

And added a reg entry DWORD value under HKEY_LOCAL_MACHINE\Software\Microsoft\Terminal Server Client

RemoteDesktop_SuppressWhenMinimized

with the value 2.

What this does is after running the bat file with admin rights it will close the RDP session but will still keep the terminal connection open to the Win Server machine allowing the tests to be run.

Now the issue on hand is that after closing the session safely the resolution that gets set for the left open session is 1024x768 while when RDP connection is open it is 1920x1200.

So finally the question which i haven't been able to answer myself: is it somehow possible to specify the resolution for the session that is kept open?


问:
Save repeated computation in conditional expression in Clojure?
In the following code, I need to compute the maximum of the sum of one element from keyboards and one from drives, subject that the sum should be less or equal to s.

```<code>  (def s 10)
  (def keyboards '(3 1))
  (def drives '(5 2 8))

  (let [k (sort (fn [x y] (> x y)) keyboards) ; sort into decreasing
        d (sort (fn [x y] (> x y)) drives)    ; sort into decreasing
        ]
    (loop [k1 (first k) ks (rest k) d1 (first d) ds (rest d)]
      (cond
        (or (nil? k1) (nil? d1)) -1     ; when one of the list is empty
        (< (+ k1 d1) s) (+ k1 d1)       ; whether (+ k1 d1) can be saved to compute once?
        (and (empty? ks) (empty? ds)) -1
        (empty? ks) (if (< (+ k1 (first ds)) s) (+ k1 (first ds)) -1) ; whether (+ k1 (first ds)) can be saved once?
        (empty? ds) (if (< (+ d1 (first ks)) s) (+ d1 (first ks)) -1) ; whether (+ d1 (first ks)) can be saved once?
        :else (let [bs (take-while #(< % s) [ (+ k1 (first ds)) (+ (first ks) d1) ])]
                (if (empty? bs) (recur (first ks) (rest ks) (first ds) (rest ds))
                    (apply max bs))))))
</code>```

As indicated in the comments, I wonder if there is any way to further optimize the repeated add operation in the conditional expressions.
It may not be optimal to use let bindings to compute them all before the condition checkings, as only one of the condition would be true, thus the computations for the other conditions would be wasted.

I wonder if Clojure compiler would be smart enough to optimize the repeated computation for me, or there is a clever expression to make the operation to be performed only once in both the checking and return value?

Any suggestion to make the code more idiomatic would be appreciated.

答:
If you want to keep the structure of your current code, you can use Mark Engelberg's better-cond library:</p>

```<code>(require '[better-cond.core :as b])

(def s 10)
(def keyboards '(3 1))
(def drives '(5 2 8))

(let [k (sort (fn [x y] (> x y)) keyboards) ; sort into decreasing
      d (sort (fn [x y] (> x y)) drives)]   ; sort into decreasing
  (loop [k1 (first k) ks (rest k) d1 (first d) ds (rest d)]
    (b/cond
      (or (nil? k1) (nil? d1)) -1           ; when one of the list is empty
      :let [x (+ k1 d1)]
      (< x s) x
      (and (empty? ks) (empty? ds)) -1
      :let [y (+ k1 (first ds))]
      (empty? ks) (if (< y s) (dec y))
      :let [z (+ d1 (first ks))]
      (empty? ds) (if (< z s) (dec z))
      :else (let [bs (take-while #(< % s) [(+ k1 (first ds)) (+ (first ks) d1)])]
              (if (empty? bs) (recur (first ks) (rest ks) (first ds) (rest ds))
                (apply max bs))))))
</code>```

Body:
In the following code, I need to compute the maximum of the sum of one element from keyboards and one from drives, subject that the sum should be less or equal to s.

  (def s 10)
  (def keyboards '(3 1))
  (def drives '(5 2 8))

  (let [k (sort (fn [x y] (> x y)) keyboards) ; sort into decreasing
        d (sort (fn [x y] (> x y)) drives)    ; sort into decreasing
        ]
    (loop [k1 (first k) ks (rest k) d1 (first d) ds (rest d)]
      (cond
        (or (nil? k1) (nil? d1)) -1     ; when one of the list is empty
        (< (+ k1 d1) s) (+ k1 d1)       ; whether (+ k1 d1) can be saved to compute once?
        (and (empty? ks) (empty? ds)) -1
        (empty? ks) (if (< (+ k1 (first ds)) s) (+ k1 (first ds)) -1) ; whether (+ k1 (first ds)) can be saved once?
        (empty? ds) (if (< (+ d1 (first ks)) s) (+ d1 (first ks)) -1) ; whether (+ d1 (first ks)) can be saved once?
        :else (let [bs (take-while #(< % s) [ (+ k1 (first ds)) (+ (first ks) d1) ])]
                (if (empty? bs) (recur (first ks) (rest ks) (first ds) (rest ds))
                    (apply max bs))))))

As indicated in the comments, I wonder if there is any way to further optimize the repeated add operation in the conditional expressions.
It may not be optimal to use let bindings to compute them all before the condition checkings, as only one of the condition would be true, thus the computations for the other conditions would be wasted.

I wonder if Clojure compiler would be smart enough to optimize the repeated computation for me, or there is a clever expression to make the operation to be performed only once in both the checking and return value?

Any suggestion to make the code more idiomatic would be appreciated.

Body:
If you want to keep the structure of your current code, you can use Mark Engelberg's better-cond library:

(require '[better-cond.core :as b])

(def s 10)
(def keyboards '(3 1))
(def drives '(5 2 8))

(let [k (sort (fn [x y] (> x y)) keyboards) ; sort into decreasing
      d (sort (fn [x y] (> x y)) drives)]   ; sort into decreasing
  (loop [k1 (first k) ks (rest k) d1 (first d) ds (rest d)]
    (b/cond
      (or (nil? k1) (nil? d1)) -1           ; when one of the list is empty
      :let [x (+ k1 d1)]
      (< x s) x
      (and (empty? ks) (empty? ds)) -1
      :let [y (+ k1 (first ds))]
      (empty? ks) (if (< y s) (dec y))
      :let [z (+ d1 (first ks))]
      (empty? ds) (if (< z s) (dec z))
      :else (let [bs (take-while #(< % s) [(+ k1 (first ds)) (+ (first ks) d1)])]
              (if (empty? bs) (recur (first ks) (rest ks) (first ds) (rest ds))
                (apply max bs))))))


问:
Why does this function fail when I use this regular expression?
I have been practicing getting more comfortable with the use of regular expressions, but I am having a really hard time understanding why this function I wrote does not work. I wrote a simple function to count the number of duplicate letters in a word, which seems to work sometimes, but doesn't work all the time.

```<code>function duplicates(str){
    try{
        return str.match(/(.)\1+/ig).length;
    }catch(e){
        return 0;
    }
}
</code>```

According to what I have researched this statement should look through the string, find a letter (or multiple letters) that repeat more than once ignoring case, and return the length of the matched letters. If no matching letters occur it will return 0. It works correctly for some strings, but not all. Here's what I have been getting:

```<code>duplicates("abcdef") -> 0      #should return 0
duplicates("Aabccdef") -> 2    #should return 2
duplicates("Mississippi") -> 3 #should return 3
duplicates("Indivisible") -> 0 #should return 1
duplicates("abcabcabc") -> 0   #should return 3
</code>```

Upon further inspection, it would seem that when I ran "Mississippi", I got the expected number 3, however when I added .toString() in replacement of .length to see what the expression was counting I got:

```<code>ss,ss,pp
</code>```

There are no i's counted and there should be. It would also seem that the i's were not counted in "Indivisible" either and did not indicate any repeated letters in "abcabcabc". It seems that it can not count non-consecutive repeats, but I can't figure out why. I am sure it is my misunderstanding of how regular expressions work, since I am new to them, but if anyone would shed some light on why this is happening, that would be awesome!

Edit: Is there a way to do this with RegEx, or do I need to use a loop?

答:
I did not investigate duplicates in 'Indivisible'.

It is not the fully answer, because the 'abcabcabc' string may be divided into the subpatterns like 'abcabc' that starts from 0 character and 'abcabc' that start from the 3 character.

It is not the fully answer, but I hope that this will be usefull

```<code>'olololo'.match(/(.+)(?=(\1))/ig)
</code>```

Body:
I have been practicing getting more comfortable with the use of regular expressions, but I am having a really hard time understanding why this function I wrote does not work. I wrote a simple function to count the number of duplicate letters in a word, which seems to work sometimes, but doesn't work all the time.

function duplicates(str){
    try{
        return str.match(/(.)\1+/ig).length;
    }catch(e){
        return 0;
    }
}

According to what I have researched this statement should look through the string, find a letter (or multiple letters) that repeat more than once ignoring case, and return the length of the matched letters. If no matching letters occur it will return 0. It works correctly for some strings, but not all. Here's what I have been getting:

duplicates("abcdef") -> 0      #should return 0
duplicates("Aabccdef") -> 2    #should return 2
duplicates("Mississippi") -> 3 #should return 3
duplicates("Indivisible") -> 0 #should return 1
duplicates("abcabcabc") -> 0   #should return 3

Upon further inspection, it would seem that when I ran "Mississippi", I got the expected number 3, however when I added .toString() in replacement of .length to see what the expression was counting I got:

ss,ss,pp

There are no i's counted and there should be. It would also seem that the i's were not counted in "Indivisible" either and did not indicate any repeated letters in "abcabcabc". It seems that it can not count non-consecutive repeats, but I can't figure out why. I am sure it is my misunderstanding of how regular expressions work, since I am new to them, but if anyone would shed some light on why this is happening, that would be awesome!

Edit: Is there a way to do this with RegEx, or do I need to use a loop?

Body:
I did not investigate duplicates in 'Indivisible'.

It is not the fully answer, because the 'abcabcabc' string may be divided into the subpatterns like 'abcabc' that starts from 0 character and 'abcabc' that start from the 3 character.

It is not the fully answer, but I hope that this will be usefull

'olololo'.match(/(.+)(?=(\1))/ig)


问:
Assign names to vector entries without assigning the vector a variable name?
In R, is it possible to assign names to components of a vector without first assigning that vector to a variable name?
The normal way is obviously:

```<code>z <- 1:3
names(z) <- c("a", "b", "c") #normal way
names(1:3) <- c("a", "b", "c") #throws an error
</code>```

The second way throws "Error in names(1:3) <- c("a", "b", "c") :
  target of assignment expands to non-language object"

According to the doc, the expression is evaluated as

```<code> z <- "names<-"(z,
     "[<-"(names(z), 3, "c2"))’.
</code>```

So no shock it doesn't work, I'm just wondering if there's a work around.

Ideally, it'd be nice to have something like:

```<code>names(z <- 1:3) <- c("a", "b", "c")
> z
a b c
1 2 3
</code>```

Just seems like a waste of space to put that on two different lines.

答:
Always thought this was a little cleaner, also don't need an additional package: </p>

```<code>z <- c(a=1, b=2, c=3)
# z
# a b c
# 1 2 3
</code>```

Body:
In R, is it possible to assign names to components of a vector without first assigning that vector to a variable name?
The normal way is obviously:

z <- 1:3
names(z) <- c("a", "b", "c") #normal way
names(1:3) <- c("a", "b", "c") #throws an error

The second way throws "Error in names(1:3) <- c("a", "b", "c") :
  target of assignment expands to non-language object"

According to the doc, the expression is evaluated as

 z <- "names<-"(z,
     "[<-"(names(z), 3, "c2"))’.

So no shock it doesn't work, I'm just wondering if there's a work around.

Ideally, it'd be nice to have something like:

names(z <- 1:3) <- c("a", "b", "c")
> z
a b c
1 2 3

Just seems like a waste of space to put that on two different lines.

Body:
Always thought this was a little cleaner, also don't need an additional package:

z <- c(a=1, b=2, c=3)
# z
# a b c
# 1 2 3


问:
WebStorm PhpStorm code reformat: how to fix comments?
WebStorm and PhpStorm allow you to reformat your code to fit the coding style set in settings (e.g.: indentation space)

I'm using this measure to fix some of the many lint errors in my project but I'm stuck at one point: is it possible to reformat all // comments to begin with a space? To go from

```<code>//My comment
</code>```

to

```<code>// My comment
</code>```

If a comment already begins with a space character, it should be left alone.

Edit: There is an option in:

"Settings >> Editor >> Code Style >> {{coding lang}} >> Other tab" to set a blank space at the start of each comment (see "Comment code" section at the bottom of this image).

However, even with that selected, using the "Reformat code" option does not fix the comments.

答:
'Add a space at comment start' option only affects 'Comment with line comment' action (Ctrl+/) behavior, it is not used by formatter.

There is currently no way to insert leading spaces on formatting, please vote for WEB-26244

Body:
WebStorm and PhpStorm allow you to reformat your code to fit the coding style set in settings (e.g.: indentation space)

I'm using this measure to fix some of the many lint errors in my project but I'm stuck at one point: is it possible to reformat all // comments to begin with a space? To go from

//My comment

to

// My comment

If a comment already begins with a space character, it should be left alone.

Edit: There is an option in:

"Settings >> Editor >> Code Style >> {{coding lang}} >> Other tab" to set a blank space at the start of each comment (see "Comment code" section at the bottom of this image).

However, even with that selected, using the "Reformat code" option does not fix the comments.


问:
Grails - how to call a controller method from a form
I'm completely new to grails, and I appreciate any help.
This code is in my gsp file:

```<code><g:form action="backfillMachineTags">
            <fieldset class="buttons">
                <g:submitButton name="create" class="save"
                                value="${message(code: 'default.button.create.label', default: 'Create')}"/>
            </fieldset>
        </g:form>
</code>```

And this code is in my RegressionPoolMachineController.groovy file:

```<code>def backfillMachineTags()
    {
        flash.message = "testing message"
        redirect(action: "list")
    }
</code>```

But when I click the submit button on the form, the method is never entered and I get a 404 not found.

message:/pool-manager/regressionPoolMachine/backfillMachineTags

status:  The requested resource is not available.

I also tried doing:

```<code><g:form url="[action:'backfillMachineTags',controller:'RegressionPoolMachineController']">
</code>```

but get a similar 404 not found.

Am I missing a step to connect my form and controller?

答:
Try adding a "controller" attribute to your form in addition to the "action" attribute.  You could use url instead of controller and action, but you would need something like
url="${createLink(controller: "myController", action: "myAction")}" instead of what you've shown here.

For reference: http://docs.grails.org/2.5.6/ref/Tags/form.html

You can also look at the generated HTML in your browser (just view source) and see what is actually being generated on the resulting web page.  That's usually pretty helpful for finding out why things aren't going where you want them to!

Body:
I'm completely new to grails, and I appreciate any help.
This code is in my gsp file:

<g:form action="backfillMachineTags">
            <fieldset class="buttons">
                <g:submitButton name="create" class="save"
                                value="${message(code: 'default.button.create.label', default: 'Create')}"/>
            </fieldset>
        </g:form>

And this code is in my RegressionPoolMachineController.groovy file:

def backfillMachineTags()
    {
        flash.message = "testing message"
        redirect(action: "list")
    }

But when I click the submit button on the form, the method is never entered and I get a 404 not found.

message:/pool-manager/regressionPoolMachine/backfillMachineTags

status:  The requested resource is not available.

I also tried doing:

<g:form url="[action:'backfillMachineTags',controller:'RegressionPoolMachineController']">

but get a similar 404 not found.

Am I missing a step to connect my form and controller?


问:
Support v7 MenuPopupHelper is now hidden and restricted to LIBRARY_GROUP
Recently i've been getting a lint error on my usage of android.support.v7.view.menu.MenuPopupHelper which is now hidden and restricted to be only used within its library group.

Exact message:

MenuPopupHelper constructor can only be called from within the same library group (groupId=com.android.support)

Excerpt from the MenuPopupHelper.java class:

```<code>/**
 * Presents a menu as a small, simple popup anchored to another view.
 *
 * @hide
 */
@RestrictTo(LIBRARY_GROUP)
public class MenuPopupHelper implements MenuHelper {
</code>```

Question:
Any idea when and why this happened ? or whats the workaround that I should look for ?

答:
Try using android.support.v7.widget.PopupMenu instead:

```<code>PopupMenu popup = new PopupMenu(v.getContext(), v);
popup.inflate(R.menu.mymenu);
//or
//popup.getMenuInflater().inflate(R.menu.mymenu, popup.getMenu());
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
    public boolean onMenuItemClick(MenuItem item) {
        final int itemId = item.getItemId();
        switch (itemId) {
            case R.id.someid:
                //do something
                return true;
            default:
                return false;
        }
    }
});
popup.show();
</code>```

Body:
Recently i've been getting a lint error on my usage of android.support.v7.view.menu.MenuPopupHelper which is now hidden and restricted to be only used within its library group.

Exact message:

MenuPopupHelper constructor can only be called from within the same library group (groupId=com.android.support)

Excerpt from the MenuPopupHelper.java class:

/**
 * Presents a menu as a small, simple popup anchored to another view.
 *
 * @hide
 */
@RestrictTo(LIBRARY_GROUP)
public class MenuPopupHelper implements MenuHelper {

Question:
Any idea when and why this happened ? or whats the workaround that I should look for ?

Body:
Try using android.support.v7.widget.PopupMenu instead:

PopupMenu popup = new PopupMenu(v.getContext(), v);
popup.inflate(R.menu.mymenu);
//or
//popup.getMenuInflater().inflate(R.menu.mymenu, popup.getMenu());
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
    public boolean onMenuItemClick(MenuItem item) {
        final int itemId = item.getItemId();
        switch (itemId) {
            case R.id.someid:
                //do something
                return true;
            default:
                return false;
        }
    }
});
popup.show();


问:
How do I split an array into smaller arrays bsaed on a condition?
Ruby 2.4.  I have an array of strings

```<code>2.4.0 :007 > arr = ["a", "b", "g", "e", "f", "i"]
 => ["a", "b", "g", "e", "f", "h", "i"]
</code>```

How do I split my array into smaller arrays based on a condition?  I have a function -- "contains_vowel," which returns true if a string contains "a", "e", "i", "o", or "u".  How would I take an array of strings and split it into smaller arrays, using a divider function of "contains_vowel"?  That is, for the above, the resulting array of smaller arrays would be

```<code>[["a"], ["b", "g"], ["e"], ["f", "h"], ["i"]]
</code>```

If an element of the larger array satisfies the condition, it would become an array of one element.

答:
One more way to skin a cat

```<code>def contains_vowel(v)
   v.count("aeiou") > 0
end
def split_by_substring_with_vowels(arr)
  arr.chunk_while do |before,after|
    !contains_vowel(before) & !contains_vowel(after)
  end.to_a
end
split_by_substring_with_vowels(arr)
#=> [["a"], ["b", "g"], ["e"], ["f", "h"], ["i"]]
</code>```

What it does:

passes each consecutive 2 elements

splits when either of them contain vowels

Example with your other Array

```<code>arr = ["1)", "dwr", "lyn,", "18,", "bbe"]
split_by_substring_with_vowels(arr)
#=> [["1)", "dwr", "lyn,", "18,"], ["bbe"]]
</code>```

Further example: (if you want vowel containing elements in succession to stay in the same group)

```<code>def split_by_substring_with_vowels(arr)
  arr.chunk_while do |before,after|
    v_before,v_after = contains_vowel(before),contains_vowel(after)
    (!v_before & !v_after) ^ (v_before & v_after)
  end.to_a
end

arr = ["1)", "dwr", "lyn,", "18,", "bbe", "re", "rr", "aa", "ee"]
split_by_substring_with_vowels(arr)
#=> [["1)", "dwr", "lyn,", "18,"], ["bbe", "re"], ["rr"], ["aa", "ee"]]
</code>```

This checks if before and after are both not vowels Or if they both are vowels

Body:
Ruby 2.4.  I have an array of strings

2.4.0 :007 > arr = ["a", "b", "g", "e", "f", "i"]
 => ["a", "b", "g", "e", "f", "h", "i"]

How do I split my array into smaller arrays based on a condition?  I have a function -- "contains_vowel," which returns true if a string contains "a", "e", "i", "o", or "u".  How would I take an array of strings and split it into smaller arrays, using a divider function of "contains_vowel"?  That is, for the above, the resulting array of smaller arrays would be

[["a"], ["b", "g"], ["e"], ["f", "h"], ["i"]]

If an element of the larger array satisfies the condition, it would become an array of one element.

Body:
One more way to skin a cat

def contains_vowel(v)
   v.count("aeiou") > 0
end
def split_by_substring_with_vowels(arr)
  arr.chunk_while do |before,after|
    !contains_vowel(before) & !contains_vowel(after)
  end.to_a
end
split_by_substring_with_vowels(arr)
#=> [["a"], ["b", "g"], ["e"], ["f", "h"], ["i"]]

What it does:

passes each consecutive 2 elements

splits when either of them contain vowels

Example with your other Array

arr = ["1)", "dwr", "lyn,", "18,", "bbe"]
split_by_substring_with_vowels(arr)
#=> [["1)", "dwr", "lyn,", "18,"], ["bbe"]]

Further example: (if you want vowel containing elements in succession to stay in the same group)

def split_by_substring_with_vowels(arr)
  arr.chunk_while do |before,after|
    v_before,v_after = contains_vowel(before),contains_vowel(after)
    (!v_before & !v_after) ^ (v_before & v_after)
  end.to_a
end

arr = ["1)", "dwr", "lyn,", "18,", "bbe", "re", "rr", "aa", "ee"]
split_by_substring_with_vowels(arr)
#=> [["1)", "dwr", "lyn,", "18,"], ["bbe", "re"], ["rr"], ["aa", "ee"]]

This checks if before and after are both not vowels Or if they both are vowels


问:
Protractor: Resolved promise is still being rejected
I'm a beginner at using Protractor and I'm using it to create a simple test automation for an add-in in Outlook.

I'm currently testing these steps:

Open an email

Click add-in button

The issue is, in one of my functions (openEmail) that uses browser.wait, the promise returned by it is rejected after being resolved.

utility.js

```<code>function waitElement(method, { container, selector, timer }) {
  let _element = container ?
    container.$(selector) : $(selector);

  return browser.wait(
    protractor.ExpectedConditions[method](_element),
    1000 * (timer || 1),
    'Unable to wait for the element'

  ).then((() => _element));
}

isClickable(options) {
  return waitElement('elementToBeClickable', options);
}
</code>```

outlook.js

```<code>let _ = require('./utility.js');

function openEmail(email) {
  _.isClickable({
    selector: email,
    timer: 15

  }).then(() => {
    console.log('OPEN EMAIL - CLICKABLE');
    el.click();

  }).catch(() => {
    throw Error('unable to click email.');
  });
}

function signIn(credentials) {
  let usernameField = $('#cred_userid_inputtext');
  let passwordField = $('#cred_password_inputtext');

  usernameField.sendKeys(credentials.username);
  passwordField.sendKeys(credentials.password);

  _.isClickable({
    selector: '#cred_sign_in_button',
    timer: 5

  }).then(el => {
    console.log('SIGN IN - CLICKABLE');
    el.click();

  }).catch(() => {
    throw Error('unable to click sign in button.');
  });
}
</code>```

test.js

```<code>let outlook = require('./outlook.js');

describe('log in', () => {

  beforeAll(() => {
    browser.ignoreSynchronization = true;
    browser.get('https://outlook.office.com');

    // credentials & cssSelector are somewhere above the file
    outlook.signIn(credentials);
    outlook.openEmail(cssSelector);
  });

  it('should display log in', () => {
    // some tests here
  });

});
</code>```

In my terminal, it logs SIGN IN - CLICKABLE and OPEN EMAIL - CLICKABLE but it also shows the error thrown by openEmail - unable to click email. I'm confused because browser.wait returns a promise, and AFAIK a resolved promise can not be rejected.

答:
Inside your openEmail(email) method, your el seems to be missing. I think your code should be

```<code> function openEmail(email) {
    _.isClickable({
selector: email,
timer: 15

}).then(el => {
console.log('OPEN EMAIL - CLICKABLE');
el.click();

}).catch(() => {
throw Error('unable to click email.');
});
}
</code>```

Body:
I'm a beginner at using Protractor and I'm using it to create a simple test automation for an add-in in Outlook.

I'm currently testing these steps:

Open an email

Click add-in button

The issue is, in one of my functions (openEmail) that uses browser.wait, the promise returned by it is rejected after being resolved.

utility.js

function waitElement(method, { container, selector, timer }) {
  let _element = container ?
    container.$(selector) : $(selector);

  return browser.wait(
    protractor.ExpectedConditions[method](_element),
    1000 * (timer || 1),
    'Unable to wait for the element'

  ).then((() => _element));
}

isClickable(options) {
  return waitElement('elementToBeClickable', options);
}

outlook.js

let _ = require('./utility.js');

function openEmail(email) {
  _.isClickable({
    selector: email,
    timer: 15

  }).then(() => {
    console.log('OPEN EMAIL - CLICKABLE');
    el.click();

  }).catch(() => {
    throw Error('unable to click email.');
  });
}

function signIn(credentials) {
  let usernameField = $('#cred_userid_inputtext');
  let passwordField = $('#cred_password_inputtext');

  usernameField.sendKeys(credentials.username);
  passwordField.sendKeys(credentials.password);

  _.isClickable({
    selector: '#cred_sign_in_button',
    timer: 5

  }).then(el => {
    console.log('SIGN IN - CLICKABLE');
    el.click();

  }).catch(() => {
    throw Error('unable to click sign in button.');
  });
}

test.js

let outlook = require('./outlook.js');

describe('log in', () => {

  beforeAll(() => {
    browser.ignoreSynchronization = true;
    browser.get('https://outlook.office.com');

    // credentials & cssSelector are somewhere above the file
    outlook.signIn(credentials);
    outlook.openEmail(cssSelector);
  });

  it('should display log in', () => {
    // some tests here
  });

});

In my terminal, it logs SIGN IN - CLICKABLE and OPEN EMAIL - CLICKABLE but it also shows the error thrown by openEmail - unable to click email. I'm confused because browser.wait returns a promise, and AFAIK a resolved promise can not be rejected.

Body:
Inside your openEmail(email) method, your el seems to be missing. I think your code should be

 function openEmail(email) {
    _.isClickable({
selector: email,
timer: 15

}).then(el => {
console.log('OPEN EMAIL - CLICKABLE');
el.click();

}).catch(() => {
throw Error('unable to click email.');
});
}


问:
jQuery/Javascript add/remove this.class on click
```<code><script>
$(".image-popup").on('click', function() {
       $(this).find(".myModal").addClass("modal-active");
       $(".modal-active").css("display", "block");
   });
$(".close").on('click', function() {
       $(".modal-active").css("display", "none");
       var myVar = $(this).closest(".image-popup");
       myVar.find(".myModal").removeClass("modal-active");
       $(".modal-active").css("display","none");
   });
</script>
</code>```

I am attempting to have a modal appear and then disappear when I click the close button. The problem is that the removeClass() will not work and the "display", "none" will not override the first click function. Any Help?

答:
You can fix it with this simple solution:

HTML

```<code><div class="image-popup">
<div class="show-modal btn btn-success">Show Modal</div>
  <div class="myModal">
  <div class="close btn btn-success">Close</div>
  <p>My Modal is active</p>
  </div>
</div>
</code>```

CSS

```<code>.modal-active .myModal{
  display: block;
}
.myModal{
  display:none;
}
.close{
  color:red;
  display:block;
}
</code>```

JS

```<code>$(function(){
    $('.show-modal').click(function(){
    $(this).parent().addClass('modal-active');
  });
  $('.close').click(function(){
    $(this).closest('.image-popup').removeClass('modal-active');
  });
});
</code>```

See this fiddle for more details https://jsfiddle.net/a3yze54w/1/

Body:
You can fix it with this simple solution:

HTML

<div class="image-popup">
<div class="show-modal btn btn-success">Show Modal</div>
  <div class="myModal">
  <div class="close btn btn-success">Close</div>
  <p>My Modal is active</p>
  </div>
</div>

CSS

.modal-active .myModal{
  display: block;
}
.myModal{
  display:none;
}
.close{
  color:red;
  display:block;
}

JS

$(function(){
    $('.show-modal').click(function(){
    $(this).parent().addClass('modal-active');
  });
  $('.close').click(function(){
    $(this).closest('.image-popup').removeClass('modal-active');
  });
});

See this fiddle for more details https://jsfiddle.net/a3yze54w/1/


问:
Google Analytics OAuth2: How to solve error: "redirect_uri_mismatch"?
I'm trying to get this example to work: https://developers.google.com/analytics/devguides/config/mgmt/v3/quickstart/web-php#enable

The error I'm getting is "Error: redirect_uri_mismatch" .

In order to install the google api resources, I used composer with this command:

```<code>php composer.phar require google/apiclient:^2.0.0@RC
</code>```

This installed the "vendor" folder in my root site folder. My index.php and oauth2callback.php files are located in the "public_html" folder.

Here's a screenshot of my error when going to my site:

The weird thing is that if I navigate to the link above that's included in the error message "Visit ...... to update the authorized..", I get this error message: " The OAuth Client Does Not Exist "

If I click on my only available Client ID, I can navigate to see the URI's which I'll screenshot below as well:

As you can see, under Authorized Javascript origins, I have http://localhost listed, and under authorized redirect URIs, I have my live site followed by the "oauthc2callback.php" file extension.

I don't understand how to get rid of the error I'm getting. I've tried replacing the URI's and putting in different JavaScript origins.

Also, for some reason on that last screenshot, it says that I don't have permission to edit this OAuth client, but I can make edits.

The code I have for index.php:

```<code><?php
// Load the Google API PHP Client Library.
require_once '../vendor/autoload.php';

// Start a session to persist credentials.
session_start();

// Create the client object and set the authorization configuration
// from the client_secretes.json you downloaded from the developer console.
$client = new Google_Client();
$client->setAuthConfigFile('../config/client_secrets.json');
$client->addScope('https://www.googleapis.com/auth/analytics.readonly');

// If the user has already authorized this app then get an access token
// else redirect to ask the user to authorize access to Google Analytics.
if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
    // Set the access token on the client.
    $client->setAccessToken($_SESSION['access_token']);

    // Create an authorized analytics service object.
    $analytics = new Google_Service_Analytics($client);

    // Get the first view (profile) id for the authorized user.
    $profile = getFirstProfileId($analytics);

    // Get the results from the Core Reporting API and print the results.
    $results = getResults($analytics, $profile);
    printResults($results);
} else {
    $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php';
    header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}

function getFirstprofileId(&$analytics) {
    // Get the user's first view (profile) ID.

    // Get the list of accounts for the authorized user.
    $accounts = $analytics->management_accounts->listManagementAccounts();

    if (count($accounts->getItems()) > 0) {
        $items = $accounts->getItems();
        $firstAccountId = $items[0]->getId();

        // Get the list of properties for the authorized user.
        $properties = $analytics->management_webproperties
        ->listManagementWebproperties($firstAccountId);

        if (count($properties->getItems()) > 0) {
            $items = $properties->getItems();
            $firstPropertyId = $items[0]->getId();

            // Get the list of views (profiles) for the authorized user.
            $profiles = $analytics->management_profiles
            ->listManagementProfiles($firstAccountId, $firstPropertyId);

            if (count($profiles->getItems()) > 0) {
                $items = $profiles->getItems();

                // Return the first view (profile) ID.
                return $items[0]->getId();

            } else {
                throw new Exception('No views (profiles) found for this user.');
            }
        } else {
            throw new Exception('No properties found for this user.');
        }
    } else {
        throw new Exception('No accounts found for this user.');
    }
}

function getResults(&$analytics, $profileId) {
    // Calls the Core Reporting API and queries for the number of sessions
    // for the last seven days.
    return $analytics->data_ga->get(
    'ga:' . $profileId,
    '7daysAgo',
    'today',
    'ga:sessions');
}

function printResults(&$results) {
    // Parses the response from the Core Reporting API and prints
    // the profile name and total sessions.
    if (count($results->getRows()) > 0) {

        // Get the profile name.
        $profileName = $results->getProfileInfo()->getProfileName();

        // Get the entry for the first entry in the first row.
        $rows = $results->getRows();
        $sessions = $rows[0][0];

        // Print the results.
        print "<p>First view (profile) found: $profileName</p>";
        print "<p>Total sessions: $sessions</p>";
    } else {
        print "<p>No results found.</p>";
    }
}
</code>```

The code I have for "oauth2callback.php":

```<code><?php
require_once '../vendor/autoload.php';

// Start a session to persist credentials.
session_start();

// Create the client object and set the authorization configuration
// from the client_secrets.json you downloaded from the Developers Console.
$client = new Google_Client();
$client->setAuthConfigFile('../config/client_secrets.json');
$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php');
$client->addScope('https://www.googleapis.com/auth/analytics.readonly');

// Handle authorization flow from the server.
if (! isset($_GET['code'])) {
    $auth_url = $client->createAuthUrl();
    header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
} else {
    $client->authenticate($_GET['code']);
    $_SESSION['access_token'] = $client->getAccessToken();
    $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/';
    header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}
</code>```

All of this code was taken from the first website example, except with a few minor additions to make it match my system.

Anyone know how I can get rid of this error? What am I doing wrong?

答:
just copy the request URI on which error is occurring from error screen and paste it to OAuth credentials "Authorised redirect URIs"

now run the app.
this works for me. Hope I answered your query.

Body:
I'm trying to get this example to work: https://developers.google.com/analytics/devguides/config/mgmt/v3/quickstart/web-php#enable

The error I'm getting is "Error: redirect_uri_mismatch" .

In order to install the google api resources, I used composer with this command:

php composer.phar require google/apiclient:^2.0.0@RC

This installed the "vendor" folder in my root site folder. My index.php and oauth2callback.php files are located in the "public_html" folder.

Here's a screenshot of my error when going to my site:

The weird thing is that if I navigate to the link above that's included in the error message "Visit ...... to update the authorized..", I get this error message: " The OAuth Client Does Not Exist "

If I click on my only available Client ID, I can navigate to see the URI's which I'll screenshot below as well:

As you can see, under Authorized Javascript origins, I have http://localhost listed, and under authorized redirect URIs, I have my live site followed by the "oauthc2callback.php" file extension.

I don't understand how to get rid of the error I'm getting. I've tried replacing the URI's and putting in different JavaScript origins.

Also, for some reason on that last screenshot, it says that I don't have permission to edit this OAuth client, but I can make edits.

The code I have for index.php:

<?php
// Load the Google API PHP Client Library.
require_once '../vendor/autoload.php';

// Start a session to persist credentials.
session_start();

// Create the client object and set the authorization configuration
// from the client_secretes.json you downloaded from the developer console.
$client = new Google_Client();
$client->setAuthConfigFile('../config/client_secrets.json');
$client->addScope('https://www.googleapis.com/auth/analytics.readonly');

// If the user has already authorized this app then get an access token
// else redirect to ask the user to authorize access to Google Analytics.
if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
    // Set the access token on the client.
    $client->setAccessToken($_SESSION['access_token']);

    // Create an authorized analytics service object.
    $analytics = new Google_Service_Analytics($client);

    // Get the first view (profile) id for the authorized user.
    $profile = getFirstProfileId($analytics);

    // Get the results from the Core Reporting API and print the results.
    $results = getResults($analytics, $profile);
    printResults($results);
} else {
    $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php';
    header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}

function getFirstprofileId(&$analytics) {
    // Get the user's first view (profile) ID.

    // Get the list of accounts for the authorized user.
    $accounts = $analytics->management_accounts->listManagementAccounts();

    if (count($accounts->getItems()) > 0) {
        $items = $accounts->getItems();
        $firstAccountId = $items[0]->getId();

        // Get the list of properties for the authorized user.
        $properties = $analytics->management_webproperties
        ->listManagementWebproperties($firstAccountId);

        if (count($properties->getItems()) > 0) {
            $items = $properties->getItems();
            $firstPropertyId = $items[0]->getId();

            // Get the list of views (profiles) for the authorized user.
            $profiles = $analytics->management_profiles
            ->listManagementProfiles($firstAccountId, $firstPropertyId);

            if (count($profiles->getItems()) > 0) {
                $items = $profiles->getItems();

                // Return the first view (profile) ID.
                return $items[0]->getId();

            } else {
                throw new Exception('No views (profiles) found for this user.');
            }
        } else {
            throw new Exception('No properties found for this user.');
        }
    } else {
        throw new Exception('No accounts found for this user.');
    }
}

function getResults(&$analytics, $profileId) {
    // Calls the Core Reporting API and queries for the number of sessions
    // for the last seven days.
    return $analytics->data_ga->get(
    'ga:' . $profileId,
    '7daysAgo',
    'today',
    'ga:sessions');
}

function printResults(&$results) {
    // Parses the response from the Core Reporting API and prints
    // the profile name and total sessions.
    if (count($results->getRows()) > 0) {

        // Get the profile name.
        $profileName = $results->getProfileInfo()->getProfileName();

        // Get the entry for the first entry in the first row.
        $rows = $results->getRows();
        $sessions = $rows[0][0];

        // Print the results.
        print "
First view (profile) found: $profileName
";
        print "
Total sessions: $sessions
";
    } else {
        print "
No results found.
";
    }
}

The code I have for "oauth2callback.php":

<?php
require_once '../vendor/autoload.php';

// Start a session to persist credentials.
session_start();

// Create the client object and set the authorization configuration
// from the client_secrets.json you downloaded from the Developers Console.
$client = new Google_Client();
$client->setAuthConfigFile('../config/client_secrets.json');
$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php');
$client->addScope('https://www.googleapis.com/auth/analytics.readonly');

// Handle authorization flow from the server.
if (! isset($_GET['code'])) {
    $auth_url = $client->createAuthUrl();
    header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
} else {
    $client->authenticate($_GET['code']);
    $_SESSION['access_token'] = $client->getAccessToken();
    $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/';
    header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}

All of this code was taken from the first website example, except with a few minor additions to make it match my system.

Anyone know how I can get rid of this error? What am I doing wrong?


问:
How to create an instance of class and implement it in a subclass?
How would I create an instance of a class to use as an attribute in another class? I believe this is what I need to do:

```<code>ClassA a1 = new ClassA(); // ClassA is the super class
</code>```

This is where I get stuck, if my above code is even correct. How do I actually use this in a subclass of ClassA, say ClassB? So if ClassA has 'name' and 'age' and ClassB has 'tenant' what do I need to do in order to give tenant a name and age?

答:
If Class B extends Class A, then you can automatically access the name and age elements of Class B as long as they are not private when declared in Class A

You can just do classBInstance.name = "bob";

Body:
How would I create an instance of a class to use as an attribute in another class? I believe this is what I need to do:

ClassA a1 = new ClassA(); // ClassA is the super class

This is where I get stuck, if my above code is even correct. How do I actually use this in a subclass of ClassA, say ClassB? So if ClassA has 'name' and 'age' and ClassB has 'tenant' what do I need to do in order to give tenant a name and age?


问:
Design patterns to avoid
A lot of people seem to agree, that the Singleton pattern has a number of drawbacks and some even suggest avoiding the pattern entirely. There's an excellent discussion here. Please direct any comments about the Singleton pattern to that question.

My question: Are there other design patterns, that should be avoided or used with great care?

答:
Patterns are complex

All design patterns should be used with care. In my opinion you should refactor towards patterns when there is a valid reason to do so instead of implementing a pattern right away. The general problem with using patterns is that they add complexity. Overuse of patterns makes a given application or system cumbersome to further develop and maintain.

Most of the time, there is a simple solution, and you won't need to apply any specific pattern. A good rule of thumb is to use a pattern whenever pieces of code tend to be replaced or need to be changed often and be prepared to take on the caveat of complex code when using a pattern.

Remember that your goal should be simplicity and employ a pattern if you see a practical need to support change in your code.

Principles over patterns

It may seem like a moot to use patterns if they can evidently lead to over-engineered and complex solutions. However it is instead much more interesting for a programmer to read up on design techniques and principles that lay the foundation for most of the patterns. In fact one of my favorite books on 'design patterns' stresses this by reiterating on what principles are applicable on the pattern in question. They are simple enough to be useful than patterns in terms of relevance. Some of the principles are general enough to encompass more than object oriented programming (OOP), such as Liskov Substitution Principle, as long as you can build modules of your code.

There are a multitude of design principles but those described in the first chapter of GoF book are quite useful to start with.

Program to an 'interface', not an 'implementation'. (Gang of Four 1995:18)

Favor 'object composition' over 'class inheritance'. (Gang of Four 1995:20)

Let those sink in on you for a while. It should be noted that when GoF was written an interface means anything that is an abstraction (which also means super classes), not to be confused with the interface as a type in Java or C#. The second principle comes from the observed overuse of inheritance which is sadly still common today.

From there you can read up on SOLID principles which was made known by Robert Cecil Martin (aka. Uncle Bob). Scott Hanselman interviewed Uncle Bob in a podcast about these principles:

Single Responsibility Principle

Open Closed Principle

Liskov Substitution Principle

Interface Segregation Principle

Dependency Inversion Principle

These principles are a good start to read up on and discuss with your peers. You may find that the principles interweave with each other and with other processes such as separation of concerns and dependency injection. After doing TDD for a while you also may find that these principles come naturally in practice as you need to follow them to some degree in order to create isolated and repeatable unit tests.

OwnerDisplayName: Brian Rasmussen

ContentLicense: CC BY-SA 2.5

Title: Design patterns to avoid

LastEditorDisplayName: Joel Coehoorn

OwnerDisplayName: Spoike

LastEditorDisplayName: Spoike


问:
php class extend approch vs static approch,which one is better
Approch 1：

```<code>class Storage extends SaeStorage {
public function save($data,$name){
    if (! $this->write ( ST_DOMAIN, $name, $data )){
        $error_message =    $this->errmsg();
        $result['error'] = $error_message;
        return $result;
    }else{
        $url = $this->getUrl ( ST_DOMAIN, $name );
        return $url;
    }
}
</code>```

}

approach 2：

```<code>class Storage  {
public static  function save($data,$name){
    $SaeStorage = new SaeStorage();
    if (! $SaeStorage->write ( ST_DOMAIN, $name, $data )){
        $error_message =    $this->errmsg();
        $result['error'] = $error_message;
        return $result;
    }else{
        $url = $SaeStorage->getUrl ( ST_DOMAIN, $name );
        return $url;
    }
}
</code>```

}

答:
Its really a design question. Both approaches are good, depends on your needs.

The first one is better if you want all the SaeStorage functionality in Storage, the second if you dont need it, only in the save method.

Anyway, I suggest the first one here, because you can use it in places where SaeStorage is in use too.

Body:
Approch 1：

class Storage extends SaeStorage {
public function save($data,$name){
    if (! $this->write ( ST_DOMAIN, $name, $data )){
        $error_message =    $this->errmsg();
        $result['error'] = $error_message;
        return $result;
    }else{
        $url = $this->getUrl ( ST_DOMAIN, $name );
        return $url;
    }
}

}

approach 2：

class Storage  {
public static  function save($data,$name){
    $SaeStorage = new SaeStorage();
    if (! $SaeStorage->write ( ST_DOMAIN, $name, $data )){
        $error_message =    $this->errmsg();
        $result['error'] = $error_message;
        return $result;
    }else{
        $url = $SaeStorage->getUrl ( ST_DOMAIN, $name );
        return $url;
    }
}

}


问:
How can I fix a corrupted Git repository?
I tried cloning my repository which I keep in my Ubuntu One folder to a new machine, and I got this:

```<code>cd ~/source/personal
git clone ~/Ubuntu\ One\ Side\ Work/projects.git/

Cloning into 'projects'...
done.
fatal: unable to read tree 29a422c19251aeaeb907175e9b3219a9bed6c616
</code>```

So I tried looking at the many other questions like this that have been asked here and most of them say to run git fsck --full and then I get this when I try that.

```<code>cd ~/Ubuntu\ One\ Side\ Work/projects.git
git fsck --full

Checking object directories: 100% (256/256), done.
Checking objects: 100% (447/447), done.
broken link from  commit 235ae1f48701d577d71ebd430344a159e5ba4881
              to  commit 984c11abfc9c2839b386f29c574d9e03383fa589
broken link from    tree 632a9cf0ef9fccea08438b574e2f1c954f4ff08b
              to    blob 25a742dff0a403b2b3884f2ffddf63eb45721fac
broken link from    tree 632a9cf0ef9fccea08438b574e2f1c954f4ff08b
              to    blob dd4e97e22e159a585b20e21028f964827d5afa4e
broken link from    tree 632a9cf0ef9fccea08438b574e2f1c954f4ff08b
              to    tree 29a422c19251aeaeb907175e9b3219a9bed6c616
broken link from    tree 632a9cf0ef9fccea08438b574e2f1c954f4ff08b
              to    tree 8084e8e04d510cc28321f30a9646477cc50c235c
broken link from    tree 774b5b4157b4caae1c6cad96c8eaf5d4eba2c628
              to    blob a0daa0c1567b55d8de2b4d7a3bc010f58c047eab
broken link from    tree 774b5b4157b4caae1c6cad96c8eaf5d4eba2c628
              to    blob e9052d35bfb6d30065b206fc43f4200a04d5281b
broken link from    tree 774b5b4157b4caae1c6cad96c8eaf5d4eba2c628
              to    blob 1a3a5e4dd2502ac121c22f743c4250e254a94eeb
broken link from    tree 4aa336dc1a5838e8918e03b85580069d83f4ad09
              to    tree 8cc55ec952dc192a233e062201d1e7e873ac3db0
broken link from    tree e5674a91a53e15575a1f3bf5786bc5cc719fb483
              to    blob 4a994e1e7bb7ce28dcec98bad48b9a891d7dec51
broken link from    tree e5674a91a53e15575a1f3bf5786bc5cc719fb483
              to    blob ac033bf9dc846101320c96a5ce8aceb8c96ec098
broken link from    tree 252ab84542264e1589576b6ee51e7a31e580a0e2
              to    tree 2069041cd5950e529e2991d37b7290ec021d90d4
broken link from    tree 2d4964aa4d4f5d8c7228518ce72ef6a63f820c6d
              to    blob d83690e1b9a6bdd8a08754b38231799acefcb2ab
broken link from    tree c7192e82fc581bd6448bda1a25e8729bdac5f4ff
              to    blob 30d54d47ae82add1917ca173d42e58b396df580b
broken link from    tree 7c66306901fc71389623286936cef172d4ffe408
              to    blob bc7e05d705401273b1df4e939de0f540597c0931
broken link from    tree 0940f5fd227d4c84d6e6749d872db50a4522ae3a
              to    tree 923767594ac22023e824948d65622fe5b407d1a1
broken link from    tree 8eadcd2a971e8357d24f0d80f993d2963452209f
              to    blob 2598bde3dc8cb80ee49510b8159344004b88645f
broken link from    tree ffa302dd0d969172ef23caeefe856ab2f57a4e4d
              to    blob d6925fa431be1ac585bf9a481e98f75107a6e6fb
broken link from    tree 7045b8870a49ce30a2027537a96d73d162bda773
              to    blob 25688652dea26f61f576ca1b52b9d1a18fbfd01d
broken link from    tree 37e4705d34bd440ce681ae32ae9a180a13256d72
              to    tree 246f564d4cee53339b8a4244f3173b61caa518eb
missing blob d6925fa431be1ac585bf9a481e98f75107a6e6fb
missing blob ac033bf9dc846101320c96a5ce8aceb8c96ec098
missing tree 29a422c19251aeaeb907175e9b3219a9bed6c616
missing tree 8084e8e04d510cc28321f30a9646477cc50c235c
missing blob 30d54d47ae82add1917ca173d42e58b396df580b
missing tree 8cc55ec952dc192a233e062201d1e7e873ac3db0
missing blob e9052d35bfb6d30065b206fc43f4200a04d5281b
dangling tree 4b26e95db542c72ac4a22ec25abe38fb2de79752
missing blob d83690e1b9a6bdd8a08754b38231799acefcb2ab
missing blob 25a742dff0a403b2b3884f2ffddf63eb45721fac
missing tree 923767594ac22023e824948d65622fe5b407d1a1
missing blob 25688652dea26f61f576ca1b52b9d1a18fbfd01d
missing blob 2598bde3dc8cb80ee49510b8159344004b88645f
dangling tree 3a683869f1bb0c1634de75700c316b3b36570dbd
dangling blob 4098d30843380d798a811f1aa9a02994f0dbbb27
missing tree 2069041cd5950e529e2991d37b7290ec021d90d4
missing blob 4a994e1e7bb7ce28dcec98bad48b9a891d7dec51
missing blob 1a3a5e4dd2502ac121c22f743c4250e254a94eeb
missing blob a0daa0c1567b55d8de2b4d7a3bc010f58c047eab
dangling tree 6c7b5162aa7a303fa3fe8dc393c5da564e309521
missing commit 984c11abfc9c2839b386f29c574d9e03383fa589
missing blob bc7e05d705401273b1df4e939de0f540597c0931
missing blob dd4e97e22e159a585b20e21028f964827d5afa4e
missing tree 246f564d4cee53339b8a4244f3173b61caa518eb
dangling commit a01f5c1e5315dc837203d6dee00d3493be9c5db9
</code>```

That looks really bad. When I do a git log | head I get this

```<code>git log | head

error: Could not read 984c11abfc9c2839b386f29c574d9e03383fa589
fatal: Failed to traverse parents of commit 235ae1f48701d577d71ebd430344a159e5ba4881
commit 2fb0d2d0643b445440f01b164f11ee9ee71fca48
Author: christopher <christopher@christopher.christopher>
Date:   Wed Aug 7 15:51:42 2013 -0400

    finishing chapter 7
</code>```

Other questions here have said to look at ./git/refs/heads/master. It's a bare repo and refs/heads/ exists but refs/heads/master does not. HEAD in the bare repository says ref: refs/heads/master though.

packed-refs does say this though

```<code># pack-refs with: peeled
2fb0d2d0643b445440f01b164f11ee9ee71fca48 refs/heads/master
</code>```

Still other questions have suggested running git reflog and no output shows up when I run that.

So I really have no idea what to do here. What strategy should be taken? Is it possible to reset head to this last commit on Aug 7?

Doing a git log and going to the bottom of the screen output shows this:

```<code>commit 996e03b949aea176238e3c7a8452700bbb987ac9
Author: christopher <christopher@christopher>
Date:   Wed Jul 3 23:00:44 2013 -0400

    many many changes
error: Could not read 984c11abfc9c2839b386f29c574d9e03383fa589
fatal: Failed to traverse parents of commit 235ae1f48701d577d71ebd430344a159e5ba4881
</code>```

That seems to be preventing the Git prune from working.

答:
Before trying any of the fixes described on this page, I would advise to make a copy of your repository and work on this copy only. Then at the end if you can fix it, compare it with the original to ensure you did not lose any file in the repair process.

Another alternative which worked for me was to reset the Git head and index to its previous state using:

git reset --keep

You can also do the same manually by opening the Git GUI and selecting each "Staged changes" and click on "Unstage the change". When everything is unstaged, you should now be able to compress your database, check your database and commit.

I also tried the following commands, but they did not work for me. But they might for you depending on the exact issue you have:

```<code>git reset --mixed
git fsck --full
git gc --auto
git prune --expire now
git reflog --all
</code>```

Finally, to avoid this problem of synchronization damaging your Git index (which can happen with Dropbox, SpiderOak, or any other cloud disk), you can do the following:

Convert your .git folder into a single "bundle" Git file by using: git bundle create my_repo.git --all, then it should work just the same as before, but since everything is in a single file you won't risk the synchronization damaging your git repo any more.

Disable instantaneous synchronization: SpiderOak allows you to set the scheduling for checking changes to "automatic" (which means that it is as soon as possible, being monitoring file changes thanks to the OS notifications). This is bad, because it will start to upload changes as soon as you are doing a change, and then download the change, so it might erase the latest changes you were just doing. A solution to fix this issue is to set the changes monitoring delay to 5 minutes or more. This also fixes issues with instant saving note taking applications (such as Notepad++).

ContentLicense: CC BY-SA 4.0

Body:
I tried cloning my repository which I keep in my Ubuntu One folder to a new machine, and I got this:

cd ~/source/personal
git clone ~/Ubuntu\ One\ Side\ Work/projects.git/

Cloning into 'projects'...
done.
fatal: unable to read tree 29a422c19251aeaeb907175e9b3219a9bed6c616

So I tried looking at the many other questions like this that have been asked here and most of them say to run git fsck --full and then I get this when I try that.

cd ~/Ubuntu\ One\ Side\ Work/projects.git
git fsck --full

Checking object directories: 100% (256/256), done.
Checking objects: 100% (447/447), done.
broken link from  commit 235ae1f48701d577d71ebd430344a159e5ba4881
              to  commit 984c11abfc9c2839b386f29c574d9e03383fa589
broken link from    tree 632a9cf0ef9fccea08438b574e2f1c954f4ff08b
              to    blob 25a742dff0a403b2b3884f2ffddf63eb45721fac
broken link from    tree 632a9cf0ef9fccea08438b574e2f1c954f4ff08b
              to    blob dd4e97e22e159a585b20e21028f964827d5afa4e
broken link from    tree 632a9cf0ef9fccea08438b574e2f1c954f4ff08b
              to    tree 29a422c19251aeaeb907175e9b3219a9bed6c616
broken link from    tree 632a9cf0ef9fccea08438b574e2f1c954f4ff08b
              to    tree 8084e8e04d510cc28321f30a9646477cc50c235c
broken link from    tree 774b5b4157b4caae1c6cad96c8eaf5d4eba2c628
              to    blob a0daa0c1567b55d8de2b4d7a3bc010f58c047eab
broken link from    tree 774b5b4157b4caae1c6cad96c8eaf5d4eba2c628
              to    blob e9052d35bfb6d30065b206fc43f4200a04d5281b
broken link from    tree 774b5b4157b4caae1c6cad96c8eaf5d4eba2c628
              to    blob 1a3a5e4dd2502ac121c22f743c4250e254a94eeb
broken link from    tree 4aa336dc1a5838e8918e03b85580069d83f4ad09
              to    tree 8cc55ec952dc192a233e062201d1e7e873ac3db0
broken link from    tree e5674a91a53e15575a1f3bf5786bc5cc719fb483
              to    blob 4a994e1e7bb7ce28dcec98bad48b9a891d7dec51
broken link from    tree e5674a91a53e15575a1f3bf5786bc5cc719fb483
              to    blob ac033bf9dc846101320c96a5ce8aceb8c96ec098
broken link from    tree 252ab84542264e1589576b6ee51e7a31e580a0e2
              to    tree 2069041cd5950e529e2991d37b7290ec021d90d4
broken link from    tree 2d4964aa4d4f5d8c7228518ce72ef6a63f820c6d
              to    blob d83690e1b9a6bdd8a08754b38231799acefcb2ab
broken link from    tree c7192e82fc581bd6448bda1a25e8729bdac5f4ff
              to    blob 30d54d47ae82add1917ca173d42e58b396df580b
broken link from    tree 7c66306901fc71389623286936cef172d4ffe408
              to    blob bc7e05d705401273b1df4e939de0f540597c0931
broken link from    tree 0940f5fd227d4c84d6e6749d872db50a4522ae3a
              to    tree 923767594ac22023e824948d65622fe5b407d1a1
broken link from    tree 8eadcd2a971e8357d24f0d80f993d2963452209f
              to    blob 2598bde3dc8cb80ee49510b8159344004b88645f
broken link from    tree ffa302dd0d969172ef23caeefe856ab2f57a4e4d
              to    blob d6925fa431be1ac585bf9a481e98f75107a6e6fb
broken link from    tree 7045b8870a49ce30a2027537a96d73d162bda773
              to    blob 25688652dea26f61f576ca1b52b9d1a18fbfd01d
broken link from    tree 37e4705d34bd440ce681ae32ae9a180a13256d72
              to    tree 246f564d4cee53339b8a4244f3173b61caa518eb
missing blob d6925fa431be1ac585bf9a481e98f75107a6e6fb
missing blob ac033bf9dc846101320c96a5ce8aceb8c96ec098
missing tree 29a422c19251aeaeb907175e9b3219a9bed6c616
missing tree 8084e8e04d510cc28321f30a9646477cc50c235c
missing blob 30d54d47ae82add1917ca173d42e58b396df580b
missing tree 8cc55ec952dc192a233e062201d1e7e873ac3db0
missing blob e9052d35bfb6d30065b206fc43f4200a04d5281b
dangling tree 4b26e95db542c72ac4a22ec25abe38fb2de79752
missing blob d83690e1b9a6bdd8a08754b38231799acefcb2ab
missing blob 25a742dff0a403b2b3884f2ffddf63eb45721fac
missing tree 923767594ac22023e824948d65622fe5b407d1a1
missing blob 25688652dea26f61f576ca1b52b9d1a18fbfd01d
missing blob 2598bde3dc8cb80ee49510b8159344004b88645f
dangling tree 3a683869f1bb0c1634de75700c316b3b36570dbd
dangling blob 4098d30843380d798a811f1aa9a02994f0dbbb27
missing tree 2069041cd5950e529e2991d37b7290ec021d90d4
missing blob 4a994e1e7bb7ce28dcec98bad48b9a891d7dec51
missing blob 1a3a5e4dd2502ac121c22f743c4250e254a94eeb
missing blob a0daa0c1567b55d8de2b4d7a3bc010f58c047eab
dangling tree 6c7b5162aa7a303fa3fe8dc393c5da564e309521
missing commit 984c11abfc9c2839b386f29c574d9e03383fa589
missing blob bc7e05d705401273b1df4e939de0f540597c0931
missing blob dd4e97e22e159a585b20e21028f964827d5afa4e
missing tree 246f564d4cee53339b8a4244f3173b61caa518eb
dangling commit a01f5c1e5315dc837203d6dee00d3493be9c5db9

That looks really bad. When I do a git log | head I get this

git log | head

error: Could not read 984c11abfc9c2839b386f29c574d9e03383fa589
fatal: Failed to traverse parents of commit 235ae1f48701d577d71ebd430344a159e5ba4881
commit 2fb0d2d0643b445440f01b164f11ee9ee71fca48
Author: christopher <christopher@christopher.christopher>
Date:   Wed Aug 7 15:51:42 2013 -0400

    finishing chapter 7

Other questions here have said to look at ./git/refs/heads/master. It's a bare repo and refs/heads/ exists but refs/heads/master does not. HEAD in the bare repository says ref: refs/heads/master though.

packed-refs does say this though

# pack-refs with: peeled
2fb0d2d0643b445440f01b164f11ee9ee71fca48 refs/heads/master

Still other questions have suggested running git reflog and no output shows up when I run that.

So I really have no idea what to do here. What strategy should be taken? Is it possible to reset head to this last commit on Aug 7?

Doing a git log and going to the bottom of the screen output shows this:

commit 996e03b949aea176238e3c7a8452700bbb987ac9
Author: christopher <christopher@christopher>
Date:   Wed Jul 3 23:00:44 2013 -0400

    many many changes
error: Could not read 984c11abfc9c2839b386f29c574d9e03383fa589
fatal: Failed to traverse parents of commit 235ae1f48701d577d71ebd430344a159e5ba4881

That seems to be preventing the Git prune from working.

Body:
Before trying any of the fixes described on this page, I would advise to make a copy of your repository and work on this copy only. Then at the end if you can fix it, compare it with the original to ensure you did not lose any file in the repair process.

Another alternative which worked for me was to reset the Git head and index to its previous state using:

git reset --keep

You can also do the same manually by opening the Git GUI and selecting each "Staged changes" and click on "Unstage the change". When everything is unstaged, you should now be able to compress your database, check your database and commit.

I also tried the following commands, but they did not work for me. But they might for you depending on the exact issue you have:

git reset --mixed
git fsck --full
git gc --auto
git prune --expire now
git reflog --all

Finally, to avoid this problem of synchronization damaging your Git index (which can happen with Dropbox, SpiderOak, or any other cloud disk), you can do the following:

Convert your .git folder into a single "bundle" Git file by using: git bundle create my_repo.git --all, then it should work just the same as before, but since everything is in a single file you won't risk the synchronization damaging your git repo any more.

Disable instantaneous synchronization: SpiderOak allows you to set the scheduling for checking changes to "automatic" (which means that it is as soon as possible, being monitoring file changes thanks to the OS notifications). This is bad, because it will start to upload changes as soon as you are doing a change, and then download the change, so it might erase the latest changes you were just doing. A solution to fix this issue is to set the changes monitoring delay to 5 minutes or more. This also fixes issues with instant saving note taking applications (such as Notepad++).