问:
How to properly configure CodeCov for a C++ w/ CMake project in TravisCI?
I was trying to configure CodeCov on my GitHub repo with TravisCI. Since my repo is in C++ and I used CMake already, I essentially copy-pasted the after_success label of this example into my .travis.yml file:

```<code>after_success:
    # Creating report
  - cd ${TRAVIS_BUILD_DIR}
  - lcov --directory . --capture --output-file coverage.info coverage info
  - lcov --remove coverage.info '/usr/*' --output-file coverage.info
  - lcov --list coverage.info
  # Uploading report to CodeCov
  - bash <(curl -s https://codecov.io/bash) || echo "Codecov did not collect coverage reports"
</code>```

I pushed a custom .codecov.yml file to provide my token and notification settings, but the after_success is just the one suggested in the example. I'm really not familiar with lcov, so I have no idea whether something else is missing or what those calls are for.

Looking at CodeCov's documentation I couldn't find what I might be missing but my coverage reports are empty because lcov can't find some mysterious .gcda file (I guess). CodeCov's docs don't mention that anywhere so I guess I'm missing an important step in my configuration (or perhaps the file can't be found for some reason...?)

This is the output of TravisCI's after_success stage:

```<code>$ lcov --directory . --capture --output-file coverage.info
Capturing coverage data from .
Found gcov version: 4.8.4
Scanning . for .gcda files ...
geninfo: ERROR: no .gcda files found in .!

$ lcov --remove coverage.info '/usr/*' --output-file coverage.info
Reading tracefile coverage.info
lcov: ERROR: no valid records found in tracefile coverage.info

$ lcov --list coverage.info
Reading tracefile coverage.info
lcov: ERROR: no valid records found in tracefile coverage.info

$ bash <(curl -s https://codecov.io/bash) || \
  echo "Codecov did not collect coverage reports"
  _____          _
 / ____|        | |
| |     ___   __| | ___  ___ _____   __
| |    / _ \ / _` |/ _ \/ __/ _ \ \ / /
| |___| (_) | (_| |  __/ (_| (_) \ V /
 \_____\___/ \__,_|\___|\___\___/ \_/
                              Bash-8fda091
==> Travis CI detected.
    project root: .
--> token set from env
    ...
==> Running gcov in . (disable via -X gcov)
==> Python coveragepy not found
==> Searching for coverage reports in:
    + .
    -> Found 3 reports
==> Detecting git/mercurial file structure
==> Appending build variables
    + TRAVIS_OS_NAME
==> Reading reports
    - Skipping empty file ./coverage.info
    + ./doc/****.zip bytes=337165           -----> That's not a report.
    + ./doc/****.pdf bytes=353614           -----> That's not a report.
==> Appending adjustments
    http://docs.codecov.io/docs/fixing-reports
    + Found adjustments
==> Uploading reports
    url: https://codecov.io
    query: branch=codecov&commit=*****...
    -> Pinging Codecov
    -> Uploading to S3 https://codecov.s3.amazonaws.com
    -> View reports at https://codecov.io/github/********
</code>```

答:
The problem was with Cmake compiler and linker flags. In order for GCov (part of GCC, and used by lcov) to provide profiling information and coverage tests some flags have to be set.

From Code Coverage for C Unit Tests:

Specifically, you need the compiler to add profiling information to the object code, which is done by adding the flags -fprofile-arcs and -ftest-coverage to your compile command.

The first flag adds logic to the object code to generate generic profiling information. This is information about how often each basic block is executed. When your program is run, all of this information will be saved to a new file with the extension .da, next to the .o file. The data in this file isn't coverage specific, but it will be used by gcov.

The second flag that you passed to GCC, -ftest-coverage, is also going to add logic to your object files. This time, the goal is to output the coverage-specific information. There are two files that will be generated, a .bb and a .bbg. The .bb file is a simple mapping file from basic blocks to line numbers. The .bbg file lists each of the arcs in the corresponding source file that were run when executing the application. This data is used by gcov to reconstruct the actual program flow graph, from which all basic block and arc execution counts can be computed.

Also, the sources need to be linked with -lgcov --coverage. In my case, since I'm using Cmake I needed to specify these with the  set_target_properties function:

```<code>add_executable(dss-sim dss-sim.cpp)
target_link_libraries(dss-sim
    list
    of
    my
    static
    libs
)
# The libs above also need to be compiled with the same flags.
set_target_properties(dss-sim
    PROPERTIES
    COMPILE_FLAGS "-ftest-coverage -fprofile-arcs"
    LINK_FLAGS    "-lgcov --coverage"
)
</code>```

Finally, since you normally don't want to include your unit tests in your coverage report, you will not define the compiler flags for them. Note, however, that if you link your unit tests with libraries that were compiled with gcov options, you'll still need to add the linker flags.

Body:
I was trying to configure CodeCov on my GitHub repo with TravisCI. Since my repo is in C++ and I used CMake already, I essentially copy-pasted the after_success label of this example into my .travis.yml file:

after_success:
    # Creating report
  - cd ${TRAVIS_BUILD_DIR}
  - lcov --directory . --capture --output-file coverage.info coverage info
  - lcov --remove coverage.info '/usr/*' --output-file coverage.info
  - lcov --list coverage.info
  # Uploading report to CodeCov
  - bash <(curl -s https://codecov.io/bash) || echo "Codecov did not collect coverage reports"

I pushed a custom .codecov.yml file to provide my token and notification settings, but the after_success is just the one suggested in the example. I'm really not familiar with lcov, so I have no idea whether something else is missing or what those calls are for.

Looking at CodeCov's documentation I couldn't find what I might be missing but my coverage reports are empty because lcov can't find some mysterious .gcda file (I guess). CodeCov's docs don't mention that anywhere so I guess I'm missing an important step in my configuration (or perhaps the file can't be found for some reason...?)

This is the output of TravisCI's after_success stage:

$ lcov --directory . --capture --output-file coverage.info
Capturing coverage data from .
Found gcov version: 4.8.4
Scanning . for .gcda files ...
geninfo: ERROR: no .gcda files found in .!

$ lcov --remove coverage.info '/usr/*' --output-file coverage.info
Reading tracefile coverage.info
lcov: ERROR: no valid records found in tracefile coverage.info

$ lcov --list coverage.info
Reading tracefile coverage.info
lcov: ERROR: no valid records found in tracefile coverage.info

$ bash <(curl -s https://codecov.io/bash) || \
  echo "Codecov did not collect coverage reports"
  _____          _
 / ____|        | |
| |     ___   __| | ___  ___ _____   __
| |    / _ \ / _` |/ _ \/ __/ _ \ \ / /
| |___| (_) | (_| |  __/ (_| (_) \ V /
 \_____\___/ \__,_|\___|\___\___/ \_/
                              Bash-8fda091
==> Travis CI detected.
    project root: .
--> token set from env
    ...
==> Running gcov in . (disable via -X gcov)
==> Python coveragepy not found
==> Searching for coverage reports in:
    + .
    -> Found 3 reports
==> Detecting git/mercurial file structure
==> Appending build variables
    + TRAVIS_OS_NAME
==> Reading reports
    - Skipping empty file ./coverage.info
    + ./doc/****.zip bytes=337165           -----> That's not a report.
    + ./doc/****.pdf bytes=353614           -----> That's not a report.
==> Appending adjustments
    http://docs.codecov.io/docs/fixing-reports
    + Found adjustments
==> Uploading reports
    url: https://codecov.io
    query: branch=codecov&commit=*****...
    -> Pinging Codecov
    -> Uploading to S3 https://codecov.s3.amazonaws.com
    -> View reports at https://codecov.io/github/********

Body:
The problem was with Cmake compiler and linker flags. In order for GCov (part of GCC, and used by lcov) to provide profiling information and coverage tests some flags have to be set.

From Code Coverage for C Unit Tests:

Specifically, you need the compiler to add profiling information to the object code, which is done by adding the flags -fprofile-arcs and -ftest-coverage to your compile command.

The first flag adds logic to the object code to generate generic profiling information. This is information about how often each basic block is executed. When your program is run, all of this information will be saved to a new file with the extension .da, next to the .o file. The data in this file isn't coverage specific, but it will be used by gcov.

The second flag that you passed to GCC, -ftest-coverage, is also going to add logic to your object files. This time, the goal is to output the coverage-specific information. There are two files that will be generated, a .bb and a .bbg. The .bb file is a simple mapping file from basic blocks to line numbers. The .bbg file lists each of the arcs in the corresponding source file that were run when executing the application. This data is used by gcov to reconstruct the actual program flow graph, from which all basic block and arc execution counts can be computed.

Also, the sources need to be linked with -lgcov --coverage. In my case, since I'm using Cmake I needed to specify these with the  set_target_properties function:

add_executable(dss-sim dss-sim.cpp)
target_link_libraries(dss-sim
    list
    of
    my
    static
    libs
)
# The libs above also need to be compiled with the same flags.
set_target_properties(dss-sim
    PROPERTIES
    COMPILE_FLAGS "-ftest-coverage -fprofile-arcs"
    LINK_FLAGS    "-lgcov --coverage"
)

Finally, since you normally don't want to include your unit tests in your coverage report, you will not define the compiler flags for them. Note, however, that if you link your unit tests with libraries that were compiled with gcov options, you'll still need to add the linker flags.


来源: stackexchange

问:
Why does this code return a list index error?
Basically it's supposed to take a set of coordinates and return a list of coordinates of it's neighbors. However, when it hits here:

```<code>if result[i][0] < 0 or result[i][0] >= board.dimensions:
    result.pop(i)
</code>```

when i is 2, it gives me an out of index error. I can manage to have it print result[2][0] but at the if statement it throws the errors. Why is this happening?

```<code>def neighborGen(row,col,board):
    """
    returns lists of coords of neighbors, in order of up, down, left, right
    """

    result = []
    result.append([row-1 , col])
    result.append([row+1 , col])
    result.append([row , col-1])
    result.append([row , col+1])

     #prune off invalid neighbors (such as (0,-1), etc etc)
     for i in range(len(result)):
        if result[i][0] < 0 or result[i][0] >= board.dimensions:
            result.pop(i)
        if result[i][1] < 0 or result[i][1] >= board.dimensions:
            result.pop(i)

    return result
</code>```

答:
```<code>def neighborGen(row,col,board):
    """
    returns lists of coords of neighbors, in order of up, down, left, right
    """

    return [
        x for x in (
            [row-1 , col], [row+1 , col], [row , col-1], [row , col+1]
        )
        if x[0] >= 0 and x[0] < board.dimensions and
        x[1] >= 0 and x[1] < board.dimensions
    ]
</code>```

ContentLicense: CC BY-SA 3.0

Body:
Basically it's supposed to take a set of coordinates and return a list of coordinates of it's neighbors. However, when it hits here:

if result[i][0] < 0 or result[i][0] >= board.dimensions:
    result.pop(i)

when i is 2, it gives me an out of index error. I can manage to have it print result[2][0] but at the if statement it throws the errors. Why is this happening?

def neighborGen(row,col,board):
    """
    returns lists of coords of neighbors, in order of up, down, left, right
    """

    result = []
    result.append([row-1 , col])
    result.append([row+1 , col])
    result.append([row , col-1])
    result.append([row , col+1])

     #prune off invalid neighbors (such as (0,-1), etc etc)
     for i in range(len(result)):
        if result[i][0] < 0 or result[i][0] >= board.dimensions:
            result.pop(i)
        if result[i][1] < 0 or result[i][1] >= board.dimensions:
            result.pop(i)

    return result

ContentLicense: CC BY-SA 2.5


问:
Query on int fields finds row, query on char field doesn't, c# oledb
Using C# and OleDB to connect to an Access database.

I have three almost identical query strings:

```<code>"select * from stock_head where sh_id = 19;"
"select * from stock_head where sh_lineno = 32059";
"select * from stock_head where sh_ref='#007705';";
</code>```

The first and second retrieve the row and the field in each case is an integer, the last one doesn't, it's a char field and the row does exist:

```<code>ExecuteQuery - select * from stock_head where sh_lineno = 32059
ID 7705, #007705, 32059, NS, 'NO SALE', 04/02/2017 14:29:00
1 row(s) found

ExecuteQuery - select * from stock_head where sh_ref='#007705';
0 row(s) found
</code>```

Is there something weird about queries on character fields via C# and OleDB?  I've tried using 'like' instead of '=', and single and double quotes to delimit the value, all to no avail.

```<code>using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.Linq;

namespace OleDbTest
{
class Program
{
    static void Main( string[] args )
    {
        // Create Profile File object
        ProcessEJFile EJP = new ProcessEJFile(
            "Provider=Microsoft.ACE.OLEDB.12.0;" +
            @"Data Source=E:\Users\sallyw\Documents\Bar.accdb;" +
            "Persist Security Info=False;");

        //// Get last reference from the Stock Header file
        //object retVal = EJP.ExecuteScalar(
        //    @"SELECT max(stock_head.[sh_ref]) FROM stock_head where sh_ref like ""[#]%"";", null);
        //string maxRef = retVal.ToString();
        //Console.WriteLine( "maxRef = {0}", maxRef );

        // Get the actual row
        string query =
             // @"select * from stock_head where sh_ref = '{0}';";
             //"select * from stock_head where sh_id = 19;";
             "select * from stock_head where sh_lineno = 32059";

        List<StockHead> shlist = EJP.GetStockHead(query, null );
        if ( shlist == null )
        {
            Console.WriteLine( "shlist is null" );
        }
        else
        {
            foreach (StockHead sh in shlist )
            {
                Console.WriteLine( sh.ToString() );
            }
            Console.WriteLine( "{0} row(s) found", shlist.Count());
        }

        query =
             // @"select * from stock_head where sh_ref = '{0}';";
             "select * from stock_head where sh_ref='#007705';";

        List<StockHead> shlist1 = EJP.GetStockHead(query, null );
        if ( shlist1 == null )
        {
            Console.WriteLine( "shlist1 is null" );
        }
        else
        {
            foreach ( StockHead sh in shlist1 )
            {
                Console.WriteLine( sh.ToString() );
            }
            Console.WriteLine( "{0} row(s) found", shlist1.Count() );
        }
        Console.ReadLine();
    }
}

class ProcessEJFile
{
    AccessDatabase Accdb = null;

    public ProcessEJFile( string connectionString )
    {
        Accdb = new AccessDatabase( connectionString );
    }

    public List<StockHead> GetStockHead( string sql, params object[] args )
    {
        DataTable t;

        Accdb.ExecuteQuery( out t, sql, args );

        if ( t != null )
        {
            List<StockHead> shlist = new List<StockHead>();

            foreach ( DataRow r in t.Rows )
            {
                StockHead sh = new StockHead( r);
                shlist.Add( sh );
            }
            return shlist;
        }
        else
        {
            return null;
        }
    }

    // Get a single value - MAX, COUNT etc.
    public Object ExecuteScalar( string sql, params object[] args )
    {
        return Accdb.ExecuteScalar( sql, args );
    }
}

class AccessDatabase
{
    public OleDbConnection conn = new OleDbConnection();

    public AccessDatabase( string connection )
    {
        conn.ConnectionString = connection;
    }

    public bool OpenDatabase()
    {
        try
        {
            conn.Open();
        }
        catch ( Exception ex )
        {
            return false;
        }
        return true;
    }

    public void CloseDatabase()
    {
        if ( conn == null )
            return;

        conn.Close();
    }

    public void ExecuteQuery( out DataTable dataTable, string sql, params object[] args )
    {
        dataTable = new DataTable();
        string query;

        // Simplified version not validating or cleaning arguments in any way
        if ( args == null )
        {
            query = sql;
        }
        else
        {
            query = string.Format( sql, args );
        }

        Console.WriteLine( "\nExecuteQuery - {0}", query );

        if ( OpenDatabase() )
        {
            OleDbCommand command = new OleDbCommand( query, conn );
            OleDbDataAdapter adapter = new OleDbDataAdapter( command );
            adapter.Fill( dataTable );
        }
    }

    public object ExecuteScalar( string sql, params object[] args )
    {
        Object returnValue = null;
        string query = sql;

        if ( OpenDatabase() )
        {
            OleDbCommand cmd = new OleDbCommand( query, (OleDbConnection)conn);
            returnValue = cmd.ExecuteScalar();
        }
        return returnValue;
    }
}

class StockHead
{
    public int sh_id;
    public string sh_ref;
    public int sh_lineno = 0;
    public string sh_type;
    public string sh_supplier = "";
    public DateTime sh_datetime;

    public StockHead( DataRow row )
    {
        this.sh_id = (int)row[ "sh_id" ];
        this.sh_ref = (string)row[ "sh_ref" ];
        if ( !string.IsNullOrEmpty( row[ "sh_lineno" ].ToString() ) )
        {
            this.sh_lineno = (int)row[ "sh_lineno" ];
        }
        this.sh_type = (string)row[ "sh_type" ];
        if ( !string.IsNullOrEmpty( row[ "sh_lineno" ].ToString() ) )
        {
            this.sh_supplier = (string)row[ "sh_supplier" ];
        }
        this.sh_datetime = (DateTime)row[ "sh_datetime" ];
    }

    public override string ToString()
    {
        return String.Format( "ID {0}, {1}, {2}, {3}, '{4}', {5}",
                this.sh_id, this.sh_ref, this.sh_lineno, this.sh_type, this.sh_supplier, this.sh_datetime );
    }
}
</code>```

}`

答:
There's nothing wrong with your query. This is failing because you try to open the connection to the database each time you perform the query by calling OpenDatabase in ExecuteQuery. The second time the OpenDatabase fails as the database is already open and the query is not executed.

You are trapping the error but doing nothing with it. The message given is...

```<code>The connection was not closed. The connection's current state is open.
</code>```

This can easily be found by stepping through your code. Did you not run it in debug?

You can change it to..

```<code>public bool OpenDatabase()
{
    try
    {
        if (conn.State != ConnectionState.Open)
        {
            conn.Open();
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
        return false;
    }
    return true;
}
</code>```

If you trap an error then do something with it other than returning False

Body:
Using C# and OleDB to connect to an Access database.

I have three almost identical query strings:

"select * from stock_head where sh_id = 19;"
"select * from stock_head where sh_lineno = 32059";
"select * from stock_head where sh_ref='#007705';";

The first and second retrieve the row and the field in each case is an integer, the last one doesn't, it's a char field and the row does exist:

ExecuteQuery - select * from stock_head where sh_lineno = 32059
ID 7705, #007705, 32059, NS, 'NO SALE', 04/02/2017 14:29:00
1 row(s) found

ExecuteQuery - select * from stock_head where sh_ref='#007705';
0 row(s) found

Is there something weird about queries on character fields via C# and OleDB?  I've tried using 'like' instead of '=', and single and double quotes to delimit the value, all to no avail.

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.Linq;

namespace OleDbTest
{
class Program
{
    static void Main( string[] args )
    {
        // Create Profile File object
        ProcessEJFile EJP = new ProcessEJFile(
            "Provider=Microsoft.ACE.OLEDB.12.0;" +
            @"Data Source=E:\Users\sallyw\Documents\Bar.accdb;" +
            "Persist Security Info=False;");

        //// Get last reference from the Stock Header file
        //object retVal = EJP.ExecuteScalar(
        //    @"SELECT max(stock_head.[sh_ref]) FROM stock_head where sh_ref like ""[#]%"";", null);
        //string maxRef = retVal.ToString();
        //Console.WriteLine( "maxRef = {0}", maxRef );

        // Get the actual row
        string query =
             // @"select * from stock_head where sh_ref = '{0}';";
             //"select * from stock_head where sh_id = 19;";
             "select * from stock_head where sh_lineno = 32059";

        List<StockHead> shlist = EJP.GetStockHead(query, null );
        if ( shlist == null )
        {
            Console.WriteLine( "shlist is null" );
        }
        else
        {
            foreach (StockHead sh in shlist )
            {
                Console.WriteLine( sh.ToString() );
            }
            Console.WriteLine( "{0} row(s) found", shlist.Count());
        }

        query =
             // @"select * from stock_head where sh_ref = '{0}';";
             "select * from stock_head where sh_ref='#007705';";

        List<StockHead> shlist1 = EJP.GetStockHead(query, null );
        if ( shlist1 == null )
        {
            Console.WriteLine( "shlist1 is null" );
        }
        else
        {
            foreach ( StockHead sh in shlist1 )
            {
                Console.WriteLine( sh.ToString() );
            }
            Console.WriteLine( "{0} row(s) found", shlist1.Count() );
        }
        Console.ReadLine();
    }
}

class ProcessEJFile
{
    AccessDatabase Accdb = null;

    public ProcessEJFile( string connectionString )
    {
        Accdb = new AccessDatabase( connectionString );
    }

    public List<StockHead> GetStockHead( string sql, params object[] args )
    {
        DataTable t;

        Accdb.ExecuteQuery( out t, sql, args );

        if ( t != null )
        {
            List<StockHead> shlist = new List<StockHead>();

            foreach ( DataRow r in t.Rows )
            {
                StockHead sh = new StockHead( r);
                shlist.Add( sh );
            }
            return shlist;
        }
        else
        {
            return null;
        }
    }

    // Get a single value - MAX, COUNT etc.
    public Object ExecuteScalar( string sql, params object[] args )
    {
        return Accdb.ExecuteScalar( sql, args );
    }
}

class AccessDatabase
{
    public OleDbConnection conn = new OleDbConnection();

    public AccessDatabase( string connection )
    {
        conn.ConnectionString = connection;
    }

    public bool OpenDatabase()
    {
        try
        {
            conn.Open();
        }
        catch ( Exception ex )
        {
            return false;
        }
        return true;
    }

    public void CloseDatabase()
    {
        if ( conn == null )
            return;

        conn.Close();
    }

    public void ExecuteQuery( out DataTable dataTable, string sql, params object[] args )
    {
        dataTable = new DataTable();
        string query;

        // Simplified version not validating or cleaning arguments in any way
        if ( args == null )
        {
            query = sql;
        }
        else
        {
            query = string.Format( sql, args );
        }

        Console.WriteLine( "\nExecuteQuery - {0}", query );

        if ( OpenDatabase() )
        {
            OleDbCommand command = new OleDbCommand( query, conn );
            OleDbDataAdapter adapter = new OleDbDataAdapter( command );
            adapter.Fill( dataTable );
        }
    }

    public object ExecuteScalar( string sql, params object[] args )
    {
        Object returnValue = null;
        string query = sql;

        if ( OpenDatabase() )
        {
            OleDbCommand cmd = new OleDbCommand( query, (OleDbConnection)conn);
            returnValue = cmd.ExecuteScalar();
        }
        return returnValue;
    }
}

class StockHead
{
    public int sh_id;
    public string sh_ref;
    public int sh_lineno = 0;
    public string sh_type;
    public string sh_supplier = "";
    public DateTime sh_datetime;

    public StockHead( DataRow row )
    {
        this.sh_id = (int)row[ "sh_id" ];
        this.sh_ref = (string)row[ "sh_ref" ];
        if ( !string.IsNullOrEmpty( row[ "sh_lineno" ].ToString() ) )
        {
            this.sh_lineno = (int)row[ "sh_lineno" ];
        }
        this.sh_type = (string)row[ "sh_type" ];
        if ( !string.IsNullOrEmpty( row[ "sh_lineno" ].ToString() ) )
        {
            this.sh_supplier = (string)row[ "sh_supplier" ];
        }
        this.sh_datetime = (DateTime)row[ "sh_datetime" ];
    }

    public override string ToString()
    {
        return String.Format( "ID {0}, {1}, {2}, {3}, '{4}', {5}",
                this.sh_id, this.sh_ref, this.sh_lineno, this.sh_type, this.sh_supplier, this.sh_datetime );
    }
}

}`

Body:
There's nothing wrong with your query. This is failing because you try to open the connection to the database each time you perform the query by calling OpenDatabase in ExecuteQuery. The second time the OpenDatabase fails as the database is already open and the query is not executed.

You are trapping the error but doing nothing with it. The message given is...

The connection was not closed. The connection's current state is open.

This can easily be found by stepping through your code. Did you not run it in debug?

You can change it to..

public bool OpenDatabase()
{
    try
    {
        if (conn.State != ConnectionState.Open)
        {
            conn.Open();
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
        return false;
    }
    return true;
}

If you trap an error then do something with it other than returning False


问:
Using VBA in Outlook to gather statistics on received emails
At work we use a shared Outlook mailbox to receive emails from our users, and at the moment we have a rota of who's turn it is to monitor the mailbox and reply etc. Our working hours have been 7am-5pm since we started the email address.

For the next 2 months we're trailing a change in hours where we (or should I say, myself only) will be monitoring the mailbox up until 11pm.

What I'd like to do is gather some statistics on the emails we receive to see if it is worth it from a business view to keep the later shift on after the trail.

What I was thinking of doing is using some VBA to check the emails in the inbox, and then break the data down into some stats for management, eg:

```<code>Monday 06/05/12:
49 emails received, 34 were replies, 15 were new
At 7am received: 0 emails
At 8am received: 1 emails
------
At 11pm received: 0 emails
</code>```

etc

To work out if an email is an original or reply I think it's easiest to see if the subject starts with RE:? (I know it's not foolproof but I think it'll work for basic stats)

Has anyone done anything like this before? Is there an easy/right way of doing it?

Anyone got any tips/code samples that would be useful?

答:
There is this nice tool called OutlookStatView made by the awesome guys at NirSoft.

screenshot sample:

if you are not so keen on using VBA, please try using the advanced filtering options available for the same, using it you can select specific folders, and start datetime and end datetime for your monitoring.

Note: this won't be realtime or automated, it is all a manual way to demonstrate the possibilities.

mailbox scan options:

Runs on Windows 2000/XP/Vista/2003/2008/7/8/10.

Supports Any version of Microsoft Outlook, including Outlook 2016.

I'm looking for Mac & Linux alternatives.

this answer is similar but not same as https://superuser.com/a/1226613/249975

Body:
At work we use a shared Outlook mailbox to receive emails from our users, and at the moment we have a rota of who's turn it is to monitor the mailbox and reply etc. Our working hours have been 7am-5pm since we started the email address.

For the next 2 months we're trailing a change in hours where we (or should I say, myself only) will be monitoring the mailbox up until 11pm.

What I'd like to do is gather some statistics on the emails we receive to see if it is worth it from a business view to keep the later shift on after the trail.

What I was thinking of doing is using some VBA to check the emails in the inbox, and then break the data down into some stats for management, eg:

Monday 06/05/12:
49 emails received, 34 were replies, 15 were new
At 7am received: 0 emails
At 8am received: 1 emails
------
At 11pm received: 0 emails

etc

To work out if an email is an original or reply I think it's easiest to see if the subject starts with RE:? (I know it's not foolproof but I think it'll work for basic stats)

Has anyone done anything like this before? Is there an easy/right way of doing it?

Anyone got any tips/code samples that would be useful?


问:
How do I show REST API and Database Connection in UML Class Diagram?
I am trying to Create Class Diagram for my Web Application but i dont know how to Represent Database Connection and REST API in Class diagrams.

P.S. I am Creating Class Diagram by following model view controller pattern.

答:
A class is a class

In your class diagrams, you model classes of your system.  And all the classes look alike:

a database connection would be a class like another, that will keep some properties about the database context and offer methods for connecting to and disconnecting from a given database.

a REST API class would be a class (or a set of classes) like any other.  If you're the API consumer you would certainly have no properties in these classes (because REST is stateless and properties create a state).  You could for example have a method for every service you could invoke.

Conceptually speaking theses classes in your system are proxies for something which is out of your system, and which would invoke the APIs provided by the database and the webservice.

But perhaps you want to model something else ?

If your system offers an API, and you want to show how the API offered to the external world relates to your internal classes, you could be interested in using a composite structure diagram.

If you want to show the different components if your system, especially how these are wired together using an API, you could be interested in the component diagram.

If your question is not so much about the structure of the classes and the deeper internals of your system, but more about showing that some part are on remote servers or in containers,  you could even think of deployment diagrams.  But these are more about the concrete layout of the operating infrastructure, and to link it to the classes, you'd need the component diagrams first.


问:
I have to pass values from on page to another page using jquery, see the below code, & suggest me changes
I have to pass values from one page to another page with jquery function (& in url). Problem is that some values are dates (with slashs), that's why its not working properly. And i also want encrypt those values.

```<code>    function gotoreq()
    {
         var baseurl = '<?php echo BASE_URL; ?>';
         var d1 = $('#date1').val(); /*date with slashs*/
         var d2 = $('#date2').val(); /*date with slashs*/
         var pid = $('#prop_ids').val();
         window.location.href = baseurl+'controller/method/'+d1+'/'+d2+'/'+pid;
    }
</code>```

Now I changed it to:

```<code>jQuery(document).on('click','#reqBook',function (event) {
             var d1 = $('#date1').val();
             d1 = d1.replace(/\//g, "-");
             var d2 = $('#date2').val();
             d2 = d2.replace(/\//g, "-");
             var pid = $('#prop_ids').val();
             window.location.href = BASE_URL+'controller/method/'+d1+'/'+d2+'/'+pid;
        });
</code>```

And In controller:

```<code>public function method($mov_in,$mov_out,$prp_id)
{
   echo $mov_in.', '.$mov_out.', '.$prp_id; exit;
}
</code>```

Its giving error of missing arguments

why this is happening?

答:
You can do this another way using localstorage to getting value from another page

Just write like this on page one.

```<code>localStorage.setItem('Date1', d1);
</code>```

And get value from another page.

```<code>var date1= localStorage.getItem('Date1');
</code>```

Body:
I have to pass values from one page to another page with jquery function (& in url). Problem is that some values are dates (with slashs), that's why its not working properly. And i also want encrypt those values.

    function gotoreq()
    {
         var baseurl = '<?php echo BASE_URL; ?>';
         var d1 = $('#date1').val(); /*date with slashs*/
         var d2 = $('#date2').val(); /*date with slashs*/
         var pid = $('#prop_ids').val();
         window.location.href = baseurl+'controller/method/'+d1+'/'+d2+'/'+pid;
    }

Now I changed it to:

jQuery(document).on('click','#reqBook',function (event) {
             var d1 = $('#date1').val();
             d1 = d1.replace(/\//g, "-");
             var d2 = $('#date2').val();
             d2 = d2.replace(/\//g, "-");
             var pid = $('#prop_ids').val();
             window.location.href = BASE_URL+'controller/method/'+d1+'/'+d2+'/'+pid;
        });

And In controller:

public function method($mov_in,$mov_out,$prp_id)
{
   echo $mov_in.', '.$mov_out.', '.$prp_id; exit;
}

Its giving error of missing arguments

why this is happening?

Body:
You can do this another way using localstorage to getting value from another page

Just write like this on page one.

localStorage.setItem('Date1', d1);

And get value from another page.

var date1= localStorage.getItem('Date1');


问:
Change foreach loop by for loop
I am creating a Fingerprint Verification System in which I have to match fingerprints using records in database.  I have used foreach loop to to so but it is taking almost 40 seconds for only 350 records.  I want to speed it up.  I want my foreach loop to convert into for loop but I am facing some difficulties in initializing the for loop.  Here is my code.

foreach (KeyValuePair<decimal, MemoryStream> tt in profileDic)
{
    this.Invoke(new Function(delegate()
    {
        textBox1.Text += "\n" + tt.Key.ToString();
    }));
    temp = new DPFP.Template(tt.Value);

    Verificator = new DPFP.Verification.Verification();
    featuresForVerification = ExtractFeatures(Sample, DPFP.Processing.DataPurpose.Verification);
    if (featuresForVerification != null)
    {
        DPFP.Verification.Verification.Result result = new DPFP.Verification.Verification.Result();
        Verificator.Verify(featuresForVerification, temp, ref result);

        #region UI Envoke
        this.Invoke(new Function(delegate()
        {
            if (result.Verified)
            {
                MessageBox.Show("FAR " + result.FARAchieved + "\n" + tt.Key.ToString());
            }
            else
            {
                //MessageBox.Show("No Match");
            }
        }));
        #endregion
    }
    this.Invoke(new Function(delegate()
    {
        progressBar1.Value += 1;
    }));
    Thread.CurrentThread.Priority = ThreadPriority.Highest;
}
```

I am confused at the first line foreach (KeyValuePair<decimal, MemoryStream> tt in profileDic).  Can someone tell me how I can iterate through every item in Dictionary object profileDic using a for loop.  I am not sure how to get KeyValuePair<decimal, MemoryStream> tt in profileDic when using a for loop.

答:
I have to match [entries against a list]. I have used foreach loop to do
  so but it is taking almost 40 seconds for only 350 records. I want to speed
  it up. I want my foreach loop to convert into for for loop [...]

At such a point it is a good idea to just step back and think about what we are doing here in general. Performance optimization usually comes on two levels: algorithms and workflow.

Essentially, the problem to be solved here is to find an entry in a potentially large set of records. There may be two causes why this is slow:

the list is very large, and iterating it takes ages

the list may not be that large, but the routine is called quite often

The list is very large

If we remember our knowledge about the so-called Big-O notation and think about it, we may quickly find that an array search takes O(n) while a hash set search for example would only take O(1) in normal cases, only in the worst case we will be again down to O(n). Not bad!

By some lucky coincident (and by the help of the cheat sheet linked above) we find out that a Dictionary<K,V> or alternatively a database index is more or less what we want: A dictionary is basically a "pimped" hash set, and a database index is typically a B-Tree, which performs with Θ(log(n)). The final decision if we should use a dictionary or a database table mostly depends on the amount of data we are talking about.

As a practical example, I recently had a piece of code on my table that iterated through a list in the same linear manner. The code did this inside of two other, nested loops. The algorithm took 4 hours to complete. After introducing two dictionaties at strategic places I had it down to under a minute. I leave it to the amused reader to calculate the percentage.

Hence, the real question to ask is not "is for faster than foreach?" (no) but instead we should ask: "How can I reorganize my data structures and optimize the algorithms involved to make it perform?"

The code is called quite often

That's another, but related problem. In some cases the data structures can't really be optimized, or it would cause way too many changes in the code. But when we closely look at what the profiler is telling us, we may find that the costly rountine is called 800.000 times in 15 seconds and that these calls alone contribute a fair amount to the total time.

If we look even closer, we may find that we call the routine with a very limited set of input data, so that essentially a large portion of the calls may just be omitted by caching the results of the costly operation. I just had such a case last week where I was able to reduce the amount of database calls down to 5% of the original amount. One can imagine what that did to overall performance.

In this second case we therefore should ask ourselves a slightly different question: "Why are we doing this at all? How can we change the logical workflow to avoid most of these calls? Is there maybe a completely different way to achieve the same results?".

Summary (TL;DR)

There are two basic approaches with every performance optimization:

Algorithmic or "low level": Quicksort or Bubblesort? Tree, List or HashSet?

Workflow and Logic: Why do we have to call that particular costly routine 5 million times?

Title: Change foreach loop by for loop

Body:
I am creating a Fingerprint Verification System in which I have to match fingerprints using records in database.  I have used foreach loop to to so but it is taking almost 40 seconds for only 350 records.  I want to speed it up.  I want my foreach loop to convert into for loop but I am facing some difficulties in initializing the for loop.  Here is my code.

foreach (KeyValuePair<decimal, MemoryStream> tt in profileDic)
{
    this.Invoke(new Function(delegate()
    {
        textBox1.Text += "\n" + tt.Key.ToString();
    }));
    temp = new DPFP.Template(tt.Value);

    Verificator = new DPFP.Verification.Verification();
    featuresForVerification = ExtractFeatures(Sample, DPFP.Processing.DataPurpose.Verification);
    if (featuresForVerification != null)
    {
        DPFP.Verification.Verification.Result result = new DPFP.Verification.Verification.Result();
        Verificator.Verify(featuresForVerification, temp, ref result);

        #region UI Envoke
        this.Invoke(new Function(delegate()
        {
            if (result.Verified)
            {
                MessageBox.Show("FAR " + result.FARAchieved + "\n" + tt.Key.ToString());
            }
            else
            {
                //MessageBox.Show("No Match");
            }
        }));
        #endregion
    }
    this.Invoke(new Function(delegate()
    {
        progressBar1.Value += 1;
    }));
    Thread.CurrentThread.Priority = ThreadPriority.Highest;
}

I am confused at the first line foreach (KeyValuePair<decimal, MemoryStream> tt in profileDic).  Can someone tell me how I can iterate through every item in Dictionary object profileDic using a for loop.  I am not sure how to get KeyValuePair<decimal, MemoryStream> tt in profileDic when using a for loop.


问:
How does Windows Store purchase work?
I'm having questions about how does exactly windows apps do the purchase. Let me clarify my question.
In UWP coding we use these codes to check if the product is purchased or not:

```<code>   var License = CurrentApp.LicenseInformation;
   var Listing = await CurrentApp.LoadListingInformationAsync();
</code>```

And the question is that, how does this method understands that if we purchased it or not? It does do an HTTP Request every time?(I need details) Or loads from a file (Again I need details, What file, where)? I used to deal with Listing Simulator and It was an XML file. I think that store saves an XML file in a place that I don't know.

It's a real question for me to understand that how it works. I found nothing in Microsoft documents.

答:
The LoadListingInformationAsync method lists all of the app meta data specific to the current market for the user. So all the product available should be provided no matter it's purchased or not.

The service works by sending requests to the Store server for the information you want. If you want to know more details, you can use fiddler to monitor the whole process when calling the method.

The LicenseInformation property loads the data from local storage. But currently there's no such documentation clarifying specific storage details.

Title: How does Windows Store purchase work?

Body:
I'm having questions about how does exactly windows apps do the purchase. Let me clarify my question.
In UWP coding we use these codes to check if the product is purchased or not:

   var License = CurrentApp.LicenseInformation;
   var Listing = await CurrentApp.LoadListingInformationAsync();

And the question is that, how does this method understands that if we purchased it or not? It does do an HTTP Request every time?(I need details) Or loads from a file (Again I need details, What file, where)? I used to deal with Listing Simulator and It was an XML file. I think that store saves an XML file in a place that I don't know.

It's a real question for me to understand that how it works. I found nothing in Microsoft documents.


问:
How to line up each word in a list so that entries start at the same point horizontally?
Here's an example I've changed slightly from a previous SO question:
http://jsfiddle.net/tPjQR/72/

ol {
    font-family: Georgia, serif;
}
ol span {
    font-family: Arial, sans-serif;
    font-size: 17px
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><ol>
    <li><span>Entry one</span></li>
    <li><span>Entry two</span></li>
    <li><span>Entrye three</span></li>
    <li><span>Entry five</span></li>
    <li><span>Entry six</span></li>
    <li><span>Entry Long Long Long Long Long Long Long Long Long Long Long Long Long Long Long Long Long</span></li>
</ol></code>```

I would like to line up the columns so that, no matter how much text is in one column, the first characters of each column will be lined up.

E.g.

not

```<code>Entry one
Entry two
Entrye three
Entry five
Entry six
</code>```

rather

```<code>Entry  one
Entry  two
Entrye three
Entry  five
Entry  six
</code>```

Is there a way to do this with list items, or do I need to use a table?

答:
An alternative method...

ol {
  list-style-type: none;
  padding: 0;
}

ol li:before {
  content: "Entry";
  display: inline-block;
  margin-right: 10px;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><ol>
  <li>one</li>
  <li>two</li>
  <li>three</li>
  <li>five</li>
  <li>six</li>
</ol></code>```

Body:
Here's an example I've changed slightly from a previous SO question:
http://jsfiddle.net/tPjQR/72/

ol {
    font-family: Georgia, serif;
}
ol span {
    font-family: Arial, sans-serif;
    font-size: 17px
}

Entry one

Entry two

Entrye three

Entry five

Entry six

Entry Long Long Long Long Long Long Long Long Long Long Long Long Long Long Long Long Long

I would like to line up the columns so that, no matter how much text is in one column, the first characters of each column will be lined up.

E.g.

not

Entry one
Entry two
Entrye three
Entry five
Entry six

rather

Entry  one
Entry  two
Entrye three
Entry  five
Entry  six

Is there a way to do this with list items, or do I need to use a table?

Body:
An alternative method...

ol {
  list-style-type: none;
  padding: 0;
}

ol li:before {
  content: "Entry";
  display: inline-block;
  margin-right: 10px;
}

<ol>
  <li>one</li>
  <li>two</li>
  <li>three</li>
  <li>five</li>
  <li>six</li>
</ol>


问:
Detached entity passed to persist when save the child data
I'm getting this error when submitting the form:

org.hibernate.PersistentObjectException: detached entity passed to persist: com.project.pmet.model.Account; nested exception is javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: com.project.pmet.model.Account

Here are my entities:

Account:

```<code>@Entity
@DynamicInsert
@DynamicUpdate
public class Account {

    @Id
    @GeneratedValue
    private Integer id;

    @Column(nullable = false)
    private String login;

    @Column(nullable = false)
    private String password;

    @Column(nullable = false)
    private String email;

    @ManyToOne
    @JoinColumn(name = "team_id")
    private Team team;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
    private List<Team> ownedTeams;

    ...
</code>```

Team:

```<code>@Entity
@DynamicInsert
@DynamicUpdate
public class Team {

    @Id
    @GeneratedValue
    private Integer id;

    @Column(nullable = false)
    private String name;

    @ManyToOne
    @JoinColumn(name = "owner_id", nullable = false)
    private Account owner;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "team")
    private List<Account> members;

    ...
</code>```

Here's a part of the Controller:

```<code>    @ModelAttribute("team")
    public Team createTeamObject() {
        return new Team();
    }

    @RequestMapping(value = "/teams/create-team", method = RequestMethod.GET)
    public String getCreateTeam(@ModelAttribute("team") Team team, Principal principal) {
        logger.info("Welcome to the create team page!");

        Account owner = accountService.findOneByLogin(principal.getName());
        team.setOwner(owner);
        team.setMembers(new AutoPopulatingList<Account>(Account.class));

        return "teams";
    }

    @RequestMapping(value = "/teams/create-team", method = RequestMethod.POST)
    public String postCreateTeam(@ModelAttribute("team") Team team) {
        logger.info("Team created!");

        teamService.save(team);

        return "redirect:/teams.html";
    }
</code>```

And the form:

```<code><form:form commandName="team" id="teamForm">
      <div class="form-group">
          <label>Name</label>
          <form:input path="name" cssClass="form-control" />
      </div>
      <div class="form-group" id="row-template">
          <label>Members</label>
          <form:select path="members[0].id" cssClass="form-control" data-live-search="true" >
             <form:options items="${accounts}" itemValue="id" />
          </form:select>
          ...
      </div>
   <form:hidden path="owner.id" />
</form:form>
</code>```

What am I doing wrong?

答: Since your id is auto generated value, don't send it from client side. I had a same issue. Make sure that you does't provide a value for auto generated attribute. </p>

ContentLicense: CC BY-SA 4.0

Body:
I'm getting this error when submitting the form:

org.hibernate.PersistentObjectException: detached entity passed to persist: com.project.pmet.model.Account; nested exception is javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: com.project.pmet.model.Account

Here are my entities:

Account:

@Entity
@DynamicInsert
@DynamicUpdate
public class Account {

    @Id
    @GeneratedValue
    private Integer id;

    @Column(nullable = false)
    private String login;

    @Column(nullable = false)
    private String password;

    @Column(nullable = false)
    private String email;

    @ManyToOne
    @JoinColumn(name = "team_id")
    private Team team;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
    private List<Team> ownedTeams;

    ...

Team:

@Entity
@DynamicInsert
@DynamicUpdate
public class Team {

    @Id
    @GeneratedValue
    private Integer id;

    @Column(nullable = false)
    private String name;

    @ManyToOne
    @JoinColumn(name = "owner_id", nullable = false)
    private Account owner;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "team")
    private List<Account> members;

    ...

Here's a part of the Controller:

    @ModelAttribute("team")
    public Team createTeamObject() {
        return new Team();
    }

    @RequestMapping(value = "/teams/create-team", method = RequestMethod.GET)
    public String getCreateTeam(@ModelAttribute("team") Team team, Principal principal) {
        logger.info("Welcome to the create team page!");

        Account owner = accountService.findOneByLogin(principal.getName());
        team.setOwner(owner);
        team.setMembers(new AutoPopulatingList<Account>(Account.class));

        return "teams";
    }

    @RequestMapping(value = "/teams/create-team", method = RequestMethod.POST)
    public String postCreateTeam(@ModelAttribute("team") Team team) {
        logger.info("Team created!");

        teamService.save(team);

        return "redirect:/teams.html";
    }

And the form:

<form:form commandName="team" id="teamForm">

          Name
          <form:input path="name" cssClass="form-control" />

          Members
          <form:select path="members[0].id" cssClass="form-control" data-live-search="true" >
             <form:options items="${accounts}" itemValue="id" />
          </form:select>
          ...

   <form:hidden path="owner.id" />
</form:form>

What am I doing wrong?


答:
I usually code as the following:

.list01 {
  width: 200px;
}
.list01 li {
  overflow: hidden;
}
.col01 {
  float: left;
  width: 5em;
}
.col02 {
  display: block;
  overflow: hidden;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><ol class="list01">
  <li><span class="col01">Entry</span><span class="col02">long long long one</span></li>
  <li><span class="col01">Entry</span><span class="col02">two</span></li>
  <li><span class="col01">Entrye</span><span class="col02">three</span></li>
  <li><span class="col01">Entry</span><span class="col02">five</span></li>
  <li><span class="col01">Entry</span><span class="col02">six</span></li>
</ol></code>```

Title: How to line up each word in a list so that entries start at the same point horizontally?

Body:
I usually code as the following:

.list01 {
  width: 200px;
}
.list01 li {
  overflow: hidden;
}
.col01 {
  float: left;
  width: 5em;
}
.col02 {
  display: block;
  overflow: hidden;
}

<ol class="list01">
  <li><span class="col01">Entry</span><span class="col02">long long long one</span></li>
  <li><span class="col01">Entry</span><span class="col02">two</span></li>
  <li><span class="col01">Entrye</span><span class="col02">three</span></li>
  <li><span class="col01">Entry</span><span class="col02">five</span></li>
  <li><span class="col01">Entry</span><span class="col02">six</span></li>
</ol>


问:
How to set my .apk file to run on different screen resolution in android?
I am using a "WVGA800" for my app. I try to run it on different resolution screens. It it is not perfectly scratching in that resolution .
I read and implement issues form this link.
http://developer.android.com/guide/practices/screens_support.html
But still not result. Please let me know if any one hase a perfect solution.
Main issue are that I am fixing hight & width of Image, textsize etc. When these are displayed
to screen of "WVGA800". But when I test them on "HVGA", "QVGA" then problem arise.
I want to avoid the "if else" conditions by getting the screen resolution at Runtime. If any one hase any solution for this...let me know. Thanks in advance.
I am also wondring when there will be new devices with new screen resolutions? </p>

答: See this, may be its helpful for you.</p>

Body: See this, may be its helpful for you.


问:
Bug with PyPy + gzip?
A very simple case:

```<code>import gzip
import cStringIO

s = 's' * 1000
buf = cStringIO.StringIO()
gzip.GzipFile(fileobj=buf, mode='wb').write(s)
buf.tell()
</code>```

Under Python 2.7, buf.tell() returns 29 and the contents of the buffer can be unzipped to reconstruct the original string.

Under PyPy 5.8.0, buf.tell() returns 10 and the contents are corrupt and cannot be unzipped.

This is also true when using the StringIO module instead of cStringIO.

Any ideas?

答:
Like kichik said, you need to close the file.  In PyPy files are not as promptly closed as in CPython.  For proof, the following code also prints 10 on CPython:

```<code>import gzip
import cStringIO

s = 's' * 1000
buf = cStringIO.StringIO()
f = gzip.GzipFile(fileobj=buf, mode='wb')
f.write(s)
print buf.tell()
</code>```

The difference with your code is only that the GzipFile object is stored in a variable f, which is still alive when buf.tell() is called; it is waiting for more data before it finishes to write the gz data to the buf file.  The proper fix is to close the file, with either f.close() or the with statement.  This is mentioned in the first paragraph of this section in the CPython difference page.

Title: Bug with PyPy + gzip?

Body:
A very simple case:

import gzip
import cStringIO

s = 's' * 1000
buf = cStringIO.StringIO()
gzip.GzipFile(fileobj=buf, mode='wb').write(s)
buf.tell()

Under Python 2.7, buf.tell() returns 29 and the contents of the buffer can be unzipped to reconstruct the original string.

Under PyPy 5.8.0, buf.tell() returns 10 and the contents are corrupt and cannot be unzipped.

This is also true when using the StringIO module instead of cStringIO.

Any ideas?

Body:
Like kichik said, you need to close the file.  In PyPy files are not as promptly closed as in CPython.  For proof, the following code also prints 10 on CPython:

import gzip
import cStringIO

s = 's' * 1000
buf = cStringIO.StringIO()
f = gzip.GzipFile(fileobj=buf, mode='wb')
f.write(s)
print buf.tell()

The difference with your code is only that the GzipFile object is stored in a variable f, which is still alive when buf.tell() is called; it is waiting for more data before it finishes to write the gz data to the buf file.  The proper fix is to close the file, with either f.close() or the with statement.  This is mentioned in the first paragraph of this section in the CPython difference page.


问:
Obfuscating the .aar files
I have created the .aar file (containing the resources & drawables) of an Android library project using

```<code>./gradlew assemble
</code>```

I have enabled obfuscating by setting minify == true

```<code>buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
</code>```

However when I run the mentioned gradle command with minify enabled = true, I get java.io.IOException: The output jar is empty. Did you specify the proper '-keep' options?

What does this error pointing to and how can I obfuscate the library .aar file?

Best Regards

答:
Copy library.pro file to your library project from this location:

```<code>...\android-sdk\tools\proguard\examples</code>```

Comment these lines when building from Android Studio, it should be probably kept/updated when building from the command line:

```<code>-injars  in.jar
-outjars out.jar
-libraryjars  /lib/rt.jar</code>```

Update your library project build.gradle file to use library.pro:

```<code>release {
  minifyEnabled true
  proguardFiles getDefaultProguardFile('proguard-android.txt'), 'library.pro'
}</code>```

Sync and build the project and it should generate an obfuscated AAR file now.

Title: Obfuscating the .aar files

Body:
I have created the .aar file (containing the resources & drawables) of an Android library project using

./gradlew assemble

I have enabled obfuscating by setting minify == true

buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

However when I run the mentioned gradle command with minify enabled = true, I get java.io.IOException: The output jar is empty. Did you specify the proper '-keep' options?

What does this error pointing to and how can I obfuscate the library .aar file?

Best Regards

Body:
Copy library.pro file to your library project from this location:

...\android-sdk\tools\proguard\examples

Comment these lines when building from Android Studio, it should be probably kept/updated when building from the command line:

-injars  in.jar
-outjars out.jar
-libraryjars  /lib/rt.jar

Update your library project build.gradle file to use library.pro:

release {
  minifyEnabled true
  proguardFiles getDefaultProguardFile('proguard-android.txt'), 'library.pro'
}

Sync and build the project and it should generate an obfuscated AAR file now.


问:
Safari 9 paints only the first frame of a video on canvas (bug)
I'm trying to paint the current frame of a <video> on a canvas but Safari 9.0.3 on 10.11 only paints the first frame… sometimes! It appears to work only after the video is cached because a hard refresh causes it to not work again.

.drawImage(video, 0, 0, width, height) is how I'm painting it.

This simple snippet works correctly in all browsers, including Safari 9 Yosemite, but not in Safari 9 El Capitan

var video = document.querySelector('video');
var canvas = document.querySelector('canvas');
canvas.addEventListener('click', function () {
  canvas
  .getContext('2d')
  .drawImage(video, 0, 0, canvas.width, canvas.height);
});```
<pre class="snippet-code-html lang-html prettyprint-override"><code><p>Play the video and then click on the canvas to paint</p>
<canvas width='240' height='135' style="border: solid;"></canvas>
<video width='240' height='135' controls loop src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"></video></code>```

Is there any workaround? Any other way to paint videos on canvas?

答:
Using blob cache seems to work even on Safari

Sample (in CoffeeScript):

```<code>prepareLocalCache: ->
    @vidtemp = document.createElement('video')
    @vidtemp.preload = 'auto'
    @xhr = new window.XMLHttpRequest
    @xhr.open 'GET', 'video link here.mp4', true
    @xhr.responseType = 'blob'
    @xhr.onload = (e) =>
      if e.currentTarget.status == 200
        myBlob = e.currentTarget.response
        @vidcache = window.URL.createObjectURL(myBlob)
        @vidtemp.src = @vidcache
    @xhr.send()

...
...

context = canvas.getContext '2d'
context.drawImage @vidtemp, 0, 0, canvas.width, canvas.height
</code>```

@vidtemp is a dynamically created video tag.

Body:
I'm trying to paint the current frame of a <video> on a canvas but Safari 9.0.3 on 10.11 only paints the first frame… sometimes! It appears to work only after the video is cached because a hard refresh causes it to not work again.

.drawImage(video, 0, 0, width, height) is how I'm painting it.

This simple snippet works correctly in all browsers, including Safari 9 Yosemite, but not in Safari 9 El Capitan

var video = document.querySelector('video');
var canvas = document.querySelector('canvas');
canvas.addEventListener('click', function () {
  canvas
  .getContext('2d')
  .drawImage(video, 0, 0, canvas.width, canvas.height);
});

Play the video and then click on the canvas to paint

<canvas width='240' height='135' style="border: solid;"></canvas>
<video width='240' height='135' controls loop src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"></video>

Is there any workaround? Any other way to paint videos on canvas?

Body:
Using blob cache seems to work even on Safari

Sample (in CoffeeScript):

prepareLocalCache: ->
    @vidtemp = document.createElement('video')
    @vidtemp.preload = 'auto'
    @xhr = new window.XMLHttpRequest
    @xhr.open 'GET', 'video link here.mp4', true
    @xhr.responseType = 'blob'
    @xhr.onload = (e) =>
      if e.currentTarget.status == 200
        myBlob = e.currentTarget.response
        @vidcache = window.URL.createObjectURL(myBlob)
        @vidtemp.src = @vidcache
    @xhr.send()

...
...

context = canvas.getContext '2d'
context.drawImage @vidtemp, 0, 0, canvas.width, canvas.height

@vidtemp is a dynamically created video tag.


问:
How to retrieve particular data from firebase?

While retrieving the data I am using this code

```<code>databaseReference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
     for (DataSnapshot data : dataSnapshot.getChildren()) {
       Firebasemodel firebasemodel = data.getValue(Firebasemodel.class);
       firebasemodels.add(firebasemodel);
    }
 }
 @Override
public void onCancelled(DatabaseError databaseError) {

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

This code snippet which returns the complete data of firebase database.

But I want to retrieve the complete data of particular users. How do I achieve it?

Thanks in advance

答:
Please use this code for getting all data:

```<code>DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference notepadRef = rootRef.child("notepad-secure").child("notepad");
ValueEventListener eventListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for(DataSnapshot ds : dataSnapshot.getChildren()) {
            String id = ds.child("id").getValue(String.class);
            String note = ds.child("note").getValue(String.class);
            String title = ds.child("title").getValue(String.class);
            String user = ds.child("user").getValue(String.class);
            Log.d("TAG", id + " / " + note + " / " + title + " / " + users);
        }
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {}
};
notepadRef.addListenerForSingleValueEvent(eventListener);
</code>```

And your output will be:

```<code>-Kono2LMSe... / sadsad / sadsad / NK46X......
</code>```

If you want to retrieve only specific data, please use this code:

```<code>DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference notepadRef = rootRef.child("notepad-secure").child("notepad").child("NK46...");
ValueEventListener eventListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
    String id = ds.child("id").getValue(String.class);
    String note = ds.child("note").getValue(String.class);
    String title = ds.child("title").getValue(String.class);
    String user = ds.child("user").getValue(String.class);
    Log.d("TAG", id + " / " + note + " / " + title + " / " + users);
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {}
};
notepadRef.addListenerForSingleValueEvent(eventListener);
</code>```

It will work for sure.

Body:
While retrieving the data I am using this code

databaseReference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
     for (DataSnapshot data : dataSnapshot.getChildren()) {
       Firebasemodel firebasemodel = data.getValue(Firebasemodel.class);
       firebasemodels.add(firebasemodel);
    }
 }
 @Override
public void onCancelled(DatabaseError databaseError) {

}
});`

This code snippet which returns the complete data of firebase database.

But I want to retrieve the complete data of particular users. How do I achieve it?

Thanks in advance

Body:
Please use this code for getting all data:

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference notepadRef = rootRef.child("notepad-secure").child("notepad");
ValueEventListener eventListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for(DataSnapshot ds : dataSnapshot.getChildren()) {
            String id = ds.child("id").getValue(String.class);
            String note = ds.child("note").getValue(String.class);
            String title = ds.child("title").getValue(String.class);
            String user = ds.child("user").getValue(String.class);
            Log.d("TAG", id + " / " + note + " / " + title + " / " + users);
        }
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {}
};
notepadRef.addListenerForSingleValueEvent(eventListener);

And your output will be:

-Kono2LMSe... / sadsad / sadsad / NK46X......

If you want to retrieve only specific data, please use this code:

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference notepadRef = rootRef.child("notepad-secure").child("notepad").child("NK46...");
ValueEventListener eventListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
    String id = ds.child("id").getValue(String.class);
    String note = ds.child("note").getValue(String.class);
    String title = ds.child("title").getValue(String.class);
    String user = ds.child("user").getValue(String.class);
    Log.d("TAG", id + " / " + note + " / " + title + " / " + users);
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {}
};
notepadRef.addListenerForSingleValueEvent(eventListener);

It will work for sure.


问:
How count common elements for every combination of rows in a matrix?
I am trying to count the common elements among each combination of rows in a dataset. I manage to do it with a nested loop which works fine for a small dataset but for the real one (1380*1380 combinations) takes too long. I wonder if there is a straightforward and less computation intensive way to do it.

```<code>a <- c(1,5,6,8,9)
b <- c(4,3,6,8,2)
c <- c(4,3,6,1,9)
df <- rbind(a,b,c)
</code>```

Result should look like this

```<code>data.frame(p1= c('a','a','a','b','b','b','c','c','c'),
           p2= c('a','b','c','a','b','c','a','b','c'),
           res= c(5,2,2,2,5,3,2,3,5))
</code>```

If it takes out comparisons between self would be even better.
Thank you very much for your help!

答:
You can do this fairly quickly for all combinations (including a x a) using data.table:

```<code>library(data.table)

# Set up data.table
DT <- data.table(p = c("a","b","c"), vec = c(list(a), list(b), list(c)))
DT[, JA := 1]
DT <- merge(DT, DT, by = "JA", allow.cartesian = TRUE)

# calculate intersection
DT[, length(intersect(unlist(vec.x),unlist(vec.y))), by = .(p.x, p.y)]
   p.x p.y V1
1:   a   a  5
2:   a   b  2
3:   a   c  3
4:   b   a  2
5:   b   b  5
6:   b   c  3
7:   c   a  3
8:   c   b  3
9:   c   c  5
</code>```

The one thing that may be tricky with your data will be initializing your data.table with a list column, but that will depend how your 1380 vectors are currently stored.

To filter out a x a, just use:

```<code>DT[p.x != p.y]
</code>```

This solution is very fast, processing 1 million rows in ~12 seconds

```<code>DT2 <- data.table(p.x = 1:1000000, p.y = 1:1000000)
DT2[, vec.x := rep(list(a), 1e6)]
DT2[, vec.y := rep(list(b), 1e6)]

system.time(DT2[, length(intersect(unlist(vec.x),unlist(vec.y))), by = .(p.x, p.y)])
user  system elapsed
11.80    0.03   12.00
</code>```

EDIT: after re-reading your example, interesction may not be what you need. If the order of the elements is important, use the following instead:

```<code>DT[, length(which(unlist(vec.x) == unlist(vec.y))), by = .(p.x, p.y)]
   p.x p.y V1
1:   a   a  5
2:   a   b  2
3:   a   c  2
4:   b   a  2
5:   b   b  5
6:   b   c  3
7:   c   a  2
8:   c   b  3
9:   c   c  5
</code>```

Body:
I am trying to count the common elements among each combination of rows in a dataset. I manage to do it with a nested loop which works fine for a small dataset but for the real one (1380*1380 combinations) takes too long. I wonder if there is a straightforward and less computation intensive way to do it.

a <- c(1,5,6,8,9)
b <- c(4,3,6,8,2)
c <- c(4,3,6,1,9)
df <- rbind(a,b,c)

Result should look like this

data.frame(p1= c('a','a','a','b','b','b','c','c','c'),
           p2= c('a','b','c','a','b','c','a','b','c'),
           res= c(5,2,2,2,5,3,2,3,5))

If it takes out comparisons between self would be even better.
Thank you very much for your help!

Body:
You can do this fairly quickly for all combinations (including a x a) using data.table:

library(data.table)

# Set up data.table
DT <- data.table(p = c("a","b","c"), vec = c(list(a), list(b), list(c)))
DT[, JA := 1]
DT <- merge(DT, DT, by = "JA", allow.cartesian = TRUE)

# calculate intersection
DT[, length(intersect(unlist(vec.x),unlist(vec.y))), by = .(p.x, p.y)]
   p.x p.y V1
1:   a   a  5
2:   a   b  2
3:   a   c  3
4:   b   a  2
5:   b   b  5
6:   b   c  3
7:   c   a  3
8:   c   b  3
9:   c   c  5

The one thing that may be tricky with your data will be initializing your data.table with a list column, but that will depend how your 1380 vectors are currently stored.

To filter out a x a, just use:

DT[p.x != p.y]

This solution is very fast, processing 1 million rows in ~12 seconds

DT2 <- data.table(p.x = 1:1000000, p.y = 1:1000000)
DT2[, vec.x := rep(list(a), 1e6)]
DT2[, vec.y := rep(list(b), 1e6)]

system.time(DT2[, length(intersect(unlist(vec.x),unlist(vec.y))), by = .(p.x, p.y)])
user  system elapsed
11.80    0.03   12.00

EDIT: after re-reading your example, interesction may not be what you need. If the order of the elements is important, use the following instead:

DT[, length(which(unlist(vec.x) == unlist(vec.y))), by = .(p.x, p.y)]
   p.x p.y V1
1:   a   a  5
2:   a   b  2
3:   a   c  2
4:   b   a  2
5:   b   b  5
6:   b   c  3
7:   c   a  2
8:   c   b  3
9:   c   c  5


问:
return search results if enter button is clicked
I have been struggling trying to trigger the button if enter button is pressed. I have tried trigger() and click() and no luck. I cannot figure out why it will not execute and the search button does work correctly when clicked with a mouse, but not when an enter button is pressed.

$(document).ready(function() {

    //alert("this");
    //$('#btnsearch').trigger('click');

$("#txtsearch").keyup(function(event){
    if(event.keyCode == 13){
        $("#btnsearch").click();
    }
});
    $('#btnsearch').click(function(event) {
        var searchText = $('#txtsearch').val();
        $.ajax({

            url: domain + "",
            type: "GET",
            headers: {
              Accept: "application/json;odata=verbose"
            },
            success: function(data) {

              $.each(data.d.results, function(index, item) {
                $('#tblResult tbody').append('
' + 'href = "' + item.Details + '">' + item.Title + '
');

              }

            )};

          event.preventDefault();

        });
    });
});```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<form class="navbar-form navbar-right">
                <div id="" class="navbar-form navbar-right">
                    <div class="input-group">
                        <input id="txtsearch" type="text" class="form-control" placeholder="Search" />
                        <div class="input-group-btn">
                            <button id="btnsearch" class="btn btn-default" type="button">
                                <i class="glyphicon glyphicon-search"></i>
                            </button>
                        </div>
                    </div>
                </div>
            </form></code>```

答:
As your input is already contained within a form element you get this behaviour by default, so the keyup handler is redundant.

The bigger issue you have is the several syntax errors in your code which you can see in the console when running the snippet in your question.

You've included Bootstrap before jQuery. It has to be the other way around

Your call to preventDefault() is inside the $.ajax settings object and causing a syntax error

The success handler function in $.ajax isn't closed properly.

When you fix those issues it works fine:

$(function() {
  $('.navbar-form').submit(function(e) {
    e.preventDefault();
    var searchText = $('#txtsearch').val();

    $.ajax({
      url: domain,
      type: "GET",
      headers: {
        Accept: "application/json;odata=verbose"
      },
      success: function(data) {
        $.each(data.d.results, function(index, item) {
          $('#tblResult tbody').append('
href="' + item.Details + '">' + item.Title + '
');
        });
      }
    });
  });
});
```

<pre class="lang-html prettyprint-override"><code><script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<form class="navbar-form navbar-right">
  <div id="" class="navbar-form navbar-right">
    <div class="input-group">
      <input id="txtsearch" type="text" class="form-control" placeholder="Search" />
      <div class="input-group-btn">
        <button id="btnsearch" class="btn btn-default" type="button">
          <i class="glyphicon glyphicon-search"></i>
      </button>
      </div>
    </div>
  </div>
</form>
</code>```

Body:
I have been struggling trying to trigger the button if enter button is pressed. I have tried trigger() and click() and no luck. I cannot figure out why it will not execute and the search button does work correctly when clicked with a mouse, but not when an enter button is pressed.

$(document).ready(function() {

    //alert("this");
    //$('#btnsearch').trigger('click');

$("#txtsearch").keyup(function(event){
    if(event.keyCode == 13){
        $("#btnsearch").click();
    }
});
    $('#btnsearch').click(function(event) {
        var searchText = $('#txtsearch').val();
        $.ajax({

            url: domain + "",
            type: "GET",
            headers: {
              Accept: "application/json;odata=verbose"
            },
            success: function(data) {

              $.each(data.d.results, function(index, item) {
                $('#tblResult tbody').append('
' + '' + item.Title + '
');

              }

            )};

          event.preventDefault();

        });
    });
});

<form class="navbar-form navbar-right">

                        <input id="txtsearch" type="text" class="form-control" placeholder="Search" />

                            <button id="btnsearch" class="btn btn-default" type="button">

                            </button>

            </form>

Body:
As your input is already contained within a form element you get this behaviour by default, so the keyup handler is redundant.

The bigger issue you have is the several syntax errors in your code which you can see in the console when running the snippet in your question.

You've included Bootstrap before jQuery. It has to be the other way around

Your call to preventDefault() is inside the $.ajax settings object and causing a syntax error

The success handler function in $.ajax isn't closed properly.

When you fix those issues it works fine:

$(function() {
  $('.navbar-form').submit(function(e) {
    e.preventDefault();
    var searchText = $('#txtsearch').val();

    $.ajax({
      url: domain,
      type: "GET",
      headers: {
        Accept: "application/json;odata=verbose"
      },
      success: function(data) {
        $.each(data.d.results, function(index, item) {
          $('#tblResult tbody').append('<tr><td><a href="' + item.Details + '">' + item.Title + '</td></tr>');
        });
      }
    });
  });
});

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<form class="navbar-form navbar-right">
  <div id="" class="navbar-form navbar-right">
    <div class="input-group">
      <input id="txtsearch" type="text" class="form-control" placeholder="Search" />
      <div class="input-group-btn">
        <button id="btnsearch" class="btn btn-default" type="button">
          <i class="glyphicon glyphicon-search"></i>
      </button>
      </div>
    </div>
  </div>
</form>


问:
Cannot read property 'style' of null - Javascript
I can't find why it is creating this error for the life of me. I am trying to change the position of "snake" with css bottom and left in javascript. Here is my code:

https://jsfiddle.net/9zewsf3x/2/

This is the what is causing the errors apparently.

```<code>snakeObject.style.bottom = x_pos + "px";
snakeObject.style.left = y_pos + "px";
</code>```

答:
You were close to what you wanted to achieve

https://jsfiddle.net/tpc8ukgj/

```<code>dummy code block for stackoverflow
</code>```

But the question itself was wrong, the error you postet did not occur!

edit:

here is the relevant part, that was missing in your script:

```<code>snakeObject.style.bottom = (parseInt(snakeObject.style.bottom) - 1) + "px";
</code>```

parseInt will remove the "px" from the value you get from style, so you can add another pixel. After that you simply add "px" again and the integer will be caseted to a string that is concatenated to the value, that you need.

Body:
I can't find why it is creating this error for the life of me. I am trying to change the position of "snake" with css bottom and left in javascript. Here is my code:

https://jsfiddle.net/9zewsf3x/2/

This is the what is causing the errors apparently.

snakeObject.style.bottom = x_pos + "px";
snakeObject.style.left = y_pos + "px";

Body:
You were close to what you wanted to achieve

https://jsfiddle.net/tpc8ukgj/

dummy code block for stackoverflow

But the question itself was wrong, the error you postet did not occur!

edit:

here is the relevant part, that was missing in your script:

snakeObject.style.bottom = (parseInt(snakeObject.style.bottom) - 1) + "px";

parseInt will remove the "px" from the value you get from style, so you can add another pixel. After that you simply add "px" again and the integer will be caseted to a string that is concatenated to the value, that you need.


问:
ios(swift) location in background (ios 9.3.2) stops working
I am not sure if this is a bug or some sort of configuration issue but(but i put every option in info.plist, locationManager.allowsBackgroundLocationUpdates = true and every other tip i found on the web and still the problem exists)

locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
}

stops updating the location after some (random) time when in background (the app closed).  On a iphone 4s ios 8.4 this problem is not present.

Maybe some one else confrunted this problem?
Thanks

答:
I have got the same problem. the way I have found to solve this problem is go to settings -> privacy -> location services -> find your app -> allow location access -> switch to never -> go back to location services -> then allow location access to switch on your service again. but only work sometimes.

also, as I know(may be I'm worry.) if the accuracy is not enough that what you have set. location update wouldn't be fired up.


问:
E/TokenRequestor: You have wrong OAuth2 related configurations, please check. Detailed error: UNREGISTERED_ON_API_CONSOLE
I am using Google Sign In via Firebase in my app. But while running the published app from Play Store, it shows following error.

```<code>E/TokenRequestor: You have wrong OAuth2 related configurations, please check. Detailed error: UNREGISTERED_ON_API_CONSOLE
</code>```

All though I have registered on Firebase, and API Console, with ids mentioned in JSON file. Following is the JSON File code

```<code>{
  "project_info": {
  "project_number": "311816357497",
  "firebase_url": "https://mcqsce.firebaseio.com",
  "project_id": "mcqsce",
  "storage_bucket": "mcqsce.appspot.com"
},
"client": [
{
  "client_info": {
    "mobilesdk_app_id": "1:311816357497:android:494b736XXXX6010b",
    "android_client_info": {
      "package_name": "in.readhere.mcqceit"
    }
  },
  "oauth_client": [
    {
      "client_id": "311816357497-9ma34c4qXXXXXXXXXXXXXoep8b24u8g.apps.googleusercontent.com",
      "client_type": 1,
      "android_info": {
        "package_name": "in.readhere.mcqceit",
        "certificate_hash": "6847ce9f7e38dc588d12345678f21c13bd25ea7c"
      }
    },
    {
      "client_id": "311816357497-5lbqnmj0bxxxxxxxxxxxxxm4qjfhmq06.apps.googleusercontent.com",
      "client_type": 3
    }
  ],
  "api_key": [
    {
      "current_key": "AIzaSyC6BGtRfxxxxxxxxxGrwwe_0V3uY9g-0dI"
    }
  ],
  "services": {
    "analytics_service": {
      "status": 1
    },
    "appinvite_service": {
      "status": 2,
      "other_platform_oauth_client": [
        {
          "client_id": "311816357497-5lbqnmj0bxxxxxxxxxxxxxxm4qjfhmq06.apps.googleusercontent.com",
          "client_type": 3
        }
       ]
     },
     "ads_service": {
       "status": 2
     }
   }
 }
 ],
 "configuration_version": "1"
}
</code>```

Following is the API Console for app
firebase console

api console

答:
Please check your build variant [Release|Debug] .
Possible errors are :
you have added SHA1 for  DEBUG and you build release apk or vice versa</p>

Body:
I am using Google Sign In via Firebase in my app. But while running the published app from Play Store, it shows following error.

E/TokenRequestor: You have wrong OAuth2 related configurations, please check. Detailed error: UNREGISTERED_ON_API_CONSOLE

All though I have registered on Firebase, and API Console, with ids mentioned in JSON file. Following is the JSON File code

{
  "project_info": {
  "project_number": "311816357497",
  "firebase_url": "https://mcqsce.firebaseio.com",
  "project_id": "mcqsce",
  "storage_bucket": "mcqsce.appspot.com"
},
"client": [
{
  "client_info": {
    "mobilesdk_app_id": "1:311816357497:android:494b736XXXX6010b",
    "android_client_info": {
      "package_name": "in.readhere.mcqceit"
    }
  },
  "oauth_client": [
    {
      "client_id": "311816357497-9ma34c4qXXXXXXXXXXXXXoep8b24u8g.apps.googleusercontent.com",
      "client_type": 1,
      "android_info": {
        "package_name": "in.readhere.mcqceit",
        "certificate_hash": "6847ce9f7e38dc588d12345678f21c13bd25ea7c"
      }
    },
    {
      "client_id": "311816357497-5lbqnmj0bxxxxxxxxxxxxxm4qjfhmq06.apps.googleusercontent.com",
      "client_type": 3
    }
  ],
  "api_key": [
    {
      "current_key": "AIzaSyC6BGtRfxxxxxxxxxGrwwe_0V3uY9g-0dI"
    }
  ],
  "services": {
    "analytics_service": {
      "status": 1
    },
    "appinvite_service": {
      "status": 2,
      "other_platform_oauth_client": [
        {
          "client_id": "311816357497-5lbqnmj0bxxxxxxxxxxxxxxm4qjfhmq06.apps.googleusercontent.com",
          "client_type": 3
        }
       ]
     },
     "ads_service": {
       "status": 2
     }
   }
 }
 ],
 "configuration_version": "1"
}

Following is the API Console for app
firebase console

api console


问:
Back To Basics: Generics in Method Sig
So my code is showing compiler errors when I try and pass the object Map<String, Future<Cache<?>> to a method with Map<String, Future<?>>. As below...

```<code>private static void logProgress(Map<String, Future<Cache<?>>> cacheLoaders, Map<String, Future<?>> cacheWriters)
            throws InterruptedException, ExecutionException {
        if (logFuturesAndCheckStillRunning("loader", cacheLoaders)
                && logFuturesAndCheckStillRunning("writer", cacheWriters)) {
            try {
                TimeUnit.SECONDS.sleep(10);
            } catch (InterruptedException e) {
                logger.error("interrupted whilst log progress slept", e);
            }
            logProgress(cacheLoaders, cacheWriters);
        }
    }

    private static boolean logFuturesAndCheckStillRunning(String context, Map<String, Future<?>> futures)
            throws InterruptedException, ExecutionException {
        boolean areStillRunning = false;
        for (String key : futures.keySet()) {
            Future<?> future = futures.get(key);
            if (future.isDone()) {
                futures.remove(key);
                logger.info("{} future has completed: {}", context, future.get());
            } else {
                logger.info("{} future is still running: {}", context, future);
                areStillRunning = true;
            }
        }
        return areStillRunning;
    }
</code>```

This should work as my method should accept a Map where the key is a String and the value is any type of Future.

The below shows I can take a cache loader future and put it into the cache writer map but I can't take a cache writer and put it into the cache loader map because the futures in the cache loader map specify the CacheLoader generic type which "in my head" is a similar concept.

```<code>            logger.info("starting cache loading");
            Map<String, Future<Cache<?>>> cacheLoaders = startCacheLoading(injector, executorLoadingService);

            logger.info("starting cache writing");
            Map<String, Future<?>> cacheWriters = startCacheWriting(injector, executorWritingService);

            Future<Cache<?>> aa = cacheLoaders.get("");
            cacheWriters.put("", aa);

            Future<?> bb = cacheWriters.get("");
            cacheLoaders.put("", bb);
</code>```

So my question is...can someone explain to me why the original code snippet has the compile error and if there's a way for me to pass both Maps with loosing the type of the values as Futures?

答:
Stripping your example back more, you're trying to compile this:

```<code>interface Cache<T> {}

static void logProgress(Map<String, Future<?>> futures) {}

public static void main (String[] args) {
    Map<String, Future<Cache<?>>> map = new HashMap<>();
    logProgress(map);  // Compiler error.
}
</code>```

Change the bound on the futures map to:

```<code>Map<String, ? extends Future<?>>
</code>```

Ideone demo

The reason your initial code doesn't work is that generics are invariant in Java: even though a Future<Cache<?>> is a Future<?>, a Map<String, Future<Cache<?>> isn't a Map<String, Future<?>>, in much the same way that a Map<String, Integer> isn't a Map<String, Object>.

If it were, your logProgress method could add a Map<Future<SomethingOtherThanCache>> to the futures map, leading to non-typesafe things happening upon return:

```<code>void logProgress(Map<String, Future<?>> futures) {
  Future<String> future = ...
  futures.put("", future);  // Compiler error, but let's pretend it's OK.
}

Map<String, Future<Cache<?>> map = new HashMap<>();
logProgress(map);  // Compiler error, but let's pretend it's OK.
Future<Cache<?>> future = map.values().iterator().next();
Cache<?> cache = future.get();  // ClassCastException here!
</code>```

Instead, you need to use the upper bound (? extends Future<?>), which makes it a compiler error for logProgress to try to put anything into the map (other than literal null).

```<code>void logProgress(Map<String, ? extends Future<?>> futures) {
  futures.put("", Futures.immediateFuture("boom!")); // Compiler error.

  futures.put("", null);  // OK.
}
</code>```

Title: Back To Basics: Generics in Method Sig

Body:
So my code is showing compiler errors when I try and pass the object Map<String, Future<Cache<?>> to a method with Map<String, Future<?>>. As below...

private static void logProgress(Map<String, Future<Cache<?>>> cacheLoaders, Map<String, Future<?>> cacheWriters)
            throws InterruptedException, ExecutionException {
        if (logFuturesAndCheckStillRunning("loader", cacheLoaders)
                && logFuturesAndCheckStillRunning("writer", cacheWriters)) {
            try {
                TimeUnit.SECONDS.sleep(10);
            } catch (InterruptedException e) {
                logger.error("interrupted whilst log progress slept", e);
            }
            logProgress(cacheLoaders, cacheWriters);
        }
    }

    private static boolean logFuturesAndCheckStillRunning(String context, Map<String, Future<?>> futures)
            throws InterruptedException, ExecutionException {
        boolean areStillRunning = false;
        for (String key : futures.keySet()) {
            Future<?> future = futures.get(key);
            if (future.isDone()) {
                futures.remove(key);
                logger.info("{} future has completed: {}", context, future.get());
            } else {
                logger.info("{} future is still running: {}", context, future);
                areStillRunning = true;
            }
        }
        return areStillRunning;
    }

This should work as my method should accept a Map where the key is a String and the value is any type of Future.

The below shows I can take a cache loader future and put it into the cache writer map but I can't take a cache writer and put it into the cache loader map because the futures in the cache loader map specify the CacheLoader generic type which "in my head" is a similar concept.

            logger.info("starting cache loading");
            Map<String, Future<Cache<?>>> cacheLoaders = startCacheLoading(injector, executorLoadingService);

            logger.info("starting cache writing");
            Map<String, Future<?>> cacheWriters = startCacheWriting(injector, executorWritingService);

            Future<Cache<?>> aa = cacheLoaders.get("");
            cacheWriters.put("", aa);

            Future<?> bb = cacheWriters.get("");
            cacheLoaders.put("", bb);

So my question is...can someone explain to me why the original code snippet has the compile error and if there's a way for me to pass both Maps with loosing the type of the values as Futures?

Body:
Stripping your example back more, you're trying to compile this:

interface Cache<T> {}

static void logProgress(Map<String, Future<?>> futures) {}

public static void main (String[] args) {
    Map<String, Future<Cache<?>>> map = new HashMap<>();
    logProgress(map);  // Compiler error.
}

Change the bound on the futures map to:

Map<String, ? extends Future<?>>

Ideone demo

The reason your initial code doesn't work is that generics are invariant in Java: even though a Future<Cache<?>> is a Future<?>, a Map<String, Future<Cache<?>> isn't a Map<String, Future<?>>, in much the same way that a Map<String, Integer> isn't a Map<String, Object>.

If it were, your logProgress method could add a Map<Future<SomethingOtherThanCache>> to the futures map, leading to non-typesafe things happening upon return:

void logProgress(Map<String, Future<?>> futures) {
  Future<String> future = ...
  futures.put("", future);  // Compiler error, but let's pretend it's OK.
}

Map<String, Future<Cache<?>> map = new HashMap<>();
logProgress(map);  // Compiler error, but let's pretend it's OK.
Future<Cache<?>> future = map.values().iterator().next();
Cache<?> cache = future.get();  // ClassCastException here!

Instead, you need to use the upper bound (? extends Future<?>), which makes it a compiler error for logProgress to try to put anything into the map (other than literal null).

void logProgress(Map<String, ? extends Future<?>> futures) {
  futures.put("", Futures.immediateFuture("boom!")); // Compiler error.

  futures.put("", null);  // OK.
}