问:
How to parse a ZIP file from by-demand-generated-InputStream without having a large byte-array?

Background

I've been trying to figure out how to deal with problematic ZIP files using a stream out of them.

The reasons for it:

Some ZIP files are not originated from a file-path. Some are from some Uri, some are even within another ZIP file.

Some ZIP files are quite problematic in opening, so together with the previous point, it is impossible to use just what the framework has to offer. Example of such files as "XAPK" files from APKPure website (example here).

As one of the possible solutions I've searched for, I asked about memory allocation via JNI, to hold the entire ZIP file inside the RAM, while using Apache's ZipFile class which can handle a zip file in various ways and not just via file-path.

The problem

Such a thing seems to work (here) very well, but it has some problems:

You don't always have the available memory.

You don't know for sure what's the max memory you are allowed to allocate without risking your app from crashing

In case you've accidentally chosen too much memory to allocate, you won't be able to catch it, and the app will crash. It's not like on Java, where you can safely use try-catch and save you from OOM (and if I'm wrong and you can, please let me know, because that's a very good thing to know about JNI) .

So, let's assume you can always create the InputStream (via Uri or from within an existing zip file), how could you parse it as a zip file?

What I've found

I've made a working sample that can do it, by using Apache's ZipFile, and letting it traverse the Zip file as if it has all in memory.

Each time it asks to read some bytes from some position, I re-create the inputStream.

It works fine, but the problem with this is that I can't optimize it well to minimize the amount of times I re-create the inputStream. I tried to at least cache the current InputStream, and that if it's good enough, re-use it (skip from current position if needed), and if the required position is before current one, re-create the inputStream. Sadly it failed in some cases (such as the XAPK file I've mentioned above), as it causes EOFException.

Currently I've worked only with Uri, but a similar solution can be done for InputStream you re-generate from within another zip-file.

Here's the inefficient solution (sample available here, including both inefficient solution and the one I tried to make better), which seems to always work well:

InefficientSeekableInputStreamByteChannel.kt

```<code>@RequiresApi(Build.VERSION_CODES.N)
abstract class InefficientSeekableInputStreamByteChannel : SeekableByteChannel {
    private var position: Long = 0L
    private var cachedSize: Long = -1L
    private var buffer = ByteArray(DEFAULT_BUFFER_SIZE)
    abstract fun getNewInputStream(): InputStream

    override fun isOpen(): Boolean = true

    override fun position(): Long = position

    override fun position(newPosition: Long): SeekableByteChannel {
//        Log.d("AppLog", "position $newPosition")
        require(newPosition >= 0L) { "Position has to be positive" }
        position = newPosition
        return this
    }

    open fun calculateSize(): Long {
        return getNewInputStream().use { inputStream: InputStream ->
            if (inputStream is FileInputStream)
                return inputStream.channel.size()
            var bytesCount = 0L
            while (true) {
                val available = inputStream.available()
                if (available == 0)
                    break
                val skip = inputStream.skip(available.toLong())
                if (skip < 0)
                    break
                bytesCount += skip
            }
            bytesCount
        }
    }

    final override fun size(): Long {
        if (cachedSize < 0L)
            cachedSize = calculateSize()
//        Log.d("AppLog", "size $cachedSize")
        return cachedSize
    }

    override fun close() {
    }

    override fun read(buf: ByteBuffer): Int {
        var wanted: Int = buf.remaining()
//        Log.d("AppLog", "read wanted:$wanted")
        if (wanted <= 0)
            return wanted
        val possible = (calculateSize() - position).toInt()
        if (possible <= 0)
            return -1
        if (wanted > possible)
            wanted = possible
        if (buffer.size < wanted)
            buffer = ByteArray(wanted)
        getNewInputStream().use { inputStream ->
            inputStream.skip(position)
            //now we have an inputStream right on the needed position
            inputStream.readBytesIntoByteArray(buffer, wanted)
        }
        buf.put(buffer, 0, wanted)
        position += wanted
        return wanted
    }

    //not needed, because we don't store anything in memory
    override fun truncate(size: Long): SeekableByteChannel = this

    override fun write(src: ByteBuffer?): Int {
        //not needed, we read only
        throw  NotImplementedError()
    }
}

</code>```

InefficientSeekableInUriByteChannel.kt

```<code>@RequiresApi(Build.VERSION_CODES.N)
class InefficientSeekableInUriByteChannel(someContext: Context, private val uri: Uri) : InefficientSeekableInputStreamByteChannel() {
    private val applicationContext = someContext.applicationContext

    override fun calculateSize(): Long = StreamsUtil.getStreamLengthFromUri(applicationContext, uri)

    override fun getNewInputStream(): InputStream = BufferedInputStream(
            applicationContext.contentResolver.openInputStream(uri)!!)
}
</code>```

Usage:

```<code>val file = ...
val uri = Uri.fromFile(file)
parseUsingInefficientSeekableInUriByteChannel(uri)
...
    private fun parseUsingInefficientSeekableInUriByteChannel(uri: Uri): Boolean {
        Log.d("AppLog", "testing using SeekableInUriByteChannel (re-creating inputStream when needed) ")
        try {
            val startTime = System.currentTimeMillis()
            ZipFile(InefficientSeekableInUriByteChannel(this, uri)).use { zipFile: ZipFile ->
                val entriesNamesAndSizes = ArrayList<Pair<String, Long>>()
                for (entry in zipFile.entries) {
                    val name = entry.name
                    val size = entry.size
                    entriesNamesAndSizes.add(Pair(name, size))
                    Log.v("Applog", "entry name: $name - ${numberFormat.format(size)}")
                }
                val endTime = System.currentTimeMillis()
                Log.d("AppLog", "got ${entriesNamesAndSizes.size} entries data. time taken: ${endTime - startTime}ms")
                return true
            }
        } catch (e: Throwable) {
            Log.e("AppLog", "error while trying to parse using SeekableInUriByteChannel:$e")
            e.printStackTrace()
        }
        return false
    }
</code>```

And here's my attempt in improving it, which didn't work in some cases:

SeekableInputStreamByteChannel.kt

```<code>@RequiresApi(Build.VERSION_CODES.N)
abstract class SeekableInputStreamByteChannel : SeekableByteChannel {
    private var position: Long = 0L
    private var actualPosition: Long = 0L
    private var cachedSize: Long = -1L
    private var inputStream: InputStream? = null
    private var buffer = ByteArray(DEFAULT_BUFFER_SIZE)
    abstract fun getNewInputStream(): InputStream

    override fun isOpen(): Boolean = true

    override fun position(): Long = position

    override fun position(newPosition: Long): SeekableByteChannel {
//        Log.d("AppLog", "position $newPosition")
        require(newPosition >= 0L) { "Position has to be positive" }
        position = newPosition
        return this
    }

    open fun calculateSize(): Long {
        return getNewInputStream().use { inputStream: InputStream ->
            if (inputStream is FileInputStream)
                return inputStream.channel.size()
            var bytesCount = 0L
            while (true) {
                val available = inputStream.available()
                if (available == 0)
                    break
                val skip = inputStream.skip(available.toLong())
                if (skip < 0)
                    break
                bytesCount += skip
            }
            bytesCount
        }
    }

    final override fun size(): Long {
        if (cachedSize < 0L)
            cachedSize = calculateSize()
//        Log.d("AppLog", "size $cachedSize")
        return cachedSize
    }

    override fun close() {
        inputStream.closeSilently().also { inputStream = null }
    }

    override fun read(buf: ByteBuffer): Int {
        var wanted: Int = buf.remaining()
//        Log.d("AppLog", "read wanted:$wanted")
        if (wanted <= 0)
            return wanted
        val possible = (calculateSize() - position).toInt()
        if (possible <= 0)
            return -1
        if (wanted > possible)
            wanted = possible
        if (buffer.size < wanted)
            buffer = ByteArray(wanted)
        var inputStream = this.inputStream
        //skipping to required position
        if (inputStream == null) {
            inputStream = getNewInputStream()
//            Log.d("AppLog", "getNewInputStream")
            inputStream.skip(position)
            this.inputStream = inputStream
        } else {
            if (actualPosition > position) {
                inputStream.close()
                actualPosition = 0L
                inputStream = getNewInputStream()
//                Log.d("AppLog", "getNewInputStream")
                this.inputStream = inputStream
            }
            inputStream.skip(position - actualPosition)
        }
        //now we have an inputStream right on the needed position
        inputStream.readBytesIntoByteArray(buffer, wanted)
        buf.put(buffer, 0, wanted)
        position += wanted
        actualPosition = position
        return wanted
    }

    //not needed, because we don't store anything in memory
    override fun truncate(size: Long): SeekableByteChannel = this

    override fun write(src: ByteBuffer?): Int {
        //not needed, we read only
        throw  NotImplementedError()
    }
}
</code>```

SeekableInUriByteChannel.kt

```<code>@RequiresApi(Build.VERSION_CODES.N)
class SeekableInUriByteChannel(someContext: Context, private val uri: Uri) : SeekableInputStreamByteChannel() {
    private val applicationContext = someContext.applicationContext

    override fun calculateSize(): Long = StreamsUtil.getStreamLengthFromUri(applicationContext, uri)

    override fun getNewInputStream(): InputStream = BufferedInputStream(
            applicationContext.contentResolver.openInputStream(uri)!!)
}

</code>```

The questions

Is there a way to improve it?

Maybe by having as little re-creation of InputStream as possible?

Are there more possible optimizations that will let it parse ZIP files well? Maybe some caching of the data?

I ask this because it seems it's quite slow compared to other solutions I've found, and I think this could help a bit.

答:
The skip() method of BufferedInputStream doesn't always skip all the bytes that you specify. In SeekableInputStreamByteChannel change the following code

```<code>inputStream.skip(position - actualPosition)
</code>```

to

```<code>var bytesToSkip = position - actualPosition
while (bytesToSkip > 0) {
    bytesToSkip -= inputStream.skip(bytesToSkip)
}
</code>```

and that should work.

Regarding making things more efficient, the first thing that ZipFile does is to zoom to the end of the file to get the central directory (CD). With the CD in hand, ZipFile knows the make up of the zip file. The zip entries should be in the same order as the files are laid out. I would read the files you want in that same order to avoid backtracking. If you can't guarantee the read order then maybe multiple input streams would make sense.

Body:
Background

I've been trying to figure out how to deal with problematic ZIP files using a stream out of them.

The reasons for it:

Some ZIP files are not originated from a file-path. Some are from some Uri, some are even within another ZIP file.

Some ZIP files are quite problematic in opening, so together with the previous point, it is impossible to use just what the framework has to offer. Example of such files as "XAPK" files from APKPure website (example here).

As one of the possible solutions I've searched for, I asked about memory allocation via JNI, to hold the entire ZIP file inside the RAM, while using Apache's ZipFile class which can handle a zip file in various ways and not just via file-path.

The problem

Such a thing seems to work (here) very well, but it has some problems:

You don't always have the available memory.

You don't know for sure what's the max memory you are allowed to allocate without risking your app from crashing

In case you've accidentally chosen too much memory to allocate, you won't be able to catch it, and the app will crash. It's not like on Java, where you can safely use try-catch and save you from OOM (and if I'm wrong and you can, please let me know, because that's a very good thing to know about JNI) .

So, let's assume you can always create the InputStream (via Uri or from within an existing zip file), how could you parse it as a zip file?

What I've found

I've made a working sample that can do it, by using Apache's ZipFile, and letting it traverse the Zip file as if it has all in memory.

Each time it asks to read some bytes from some position, I re-create the inputStream.

It works fine, but the problem with this is that I can't optimize it well to minimize the amount of times I re-create the inputStream. I tried to at least cache the current InputStream, and that if it's good enough, re-use it (skip from current position if needed), and if the required position is before current one, re-create the inputStream. Sadly it failed in some cases (such as the XAPK file I've mentioned above), as it causes EOFException.

Currently I've worked only with Uri, but a similar solution can be done for InputStream you re-generate from within another zip-file.

Here's the inefficient solution (sample available here, including both inefficient solution and the one I tried to make better), which seems to always work well:

InefficientSeekableInputStreamByteChannel.kt

@RequiresApi(Build.VERSION_CODES.N)
abstract class InefficientSeekableInputStreamByteChannel : SeekableByteChannel {
    private var position: Long = 0L
    private var cachedSize: Long = -1L
    private var buffer = ByteArray(DEFAULT_BUFFER_SIZE)
    abstract fun getNewInputStream(): InputStream

    override fun isOpen(): Boolean = true

    override fun position(): Long = position

    override fun position(newPosition: Long): SeekableByteChannel {
//        Log.d("AppLog", "position $newPosition")
        require(newPosition >= 0L) { "Position has to be positive" }
        position = newPosition
        return this
    }

    open fun calculateSize(): Long {
        return getNewInputStream().use { inputStream: InputStream ->
            if (inputStream is FileInputStream)
                return inputStream.channel.size()
            var bytesCount = 0L
            while (true) {
                val available = inputStream.available()
                if (available == 0)
                    break
                val skip = inputStream.skip(available.toLong())
                if (skip < 0)
                    break
                bytesCount += skip
            }
            bytesCount
        }
    }

    final override fun size(): Long {
        if (cachedSize < 0L)
            cachedSize = calculateSize()
//        Log.d("AppLog", "size $cachedSize")
        return cachedSize
    }

    override fun close() {
    }

    override fun read(buf: ByteBuffer): Int {
        var wanted: Int = buf.remaining()
//        Log.d("AppLog", "read wanted:$wanted")
        if (wanted <= 0)
            return wanted
        val possible = (calculateSize() - position).toInt()
        if (possible <= 0)
            return -1
        if (wanted > possible)
            wanted = possible
        if (buffer.size < wanted)
            buffer = ByteArray(wanted)
        getNewInputStream().use { inputStream ->
            inputStream.skip(position)
            //now we have an inputStream right on the needed position
            inputStream.readBytesIntoByteArray(buffer, wanted)
        }
        buf.put(buffer, 0, wanted)
        position += wanted
        return wanted
    }

    //not needed, because we don't store anything in memory
    override fun truncate(size: Long): SeekableByteChannel = this

    override fun write(src: ByteBuffer?): Int {
        //not needed, we read only
        throw  NotImplementedError()
    }
}

InefficientSeekableInUriByteChannel.kt

@RequiresApi(Build.VERSION_CODES.N)
class InefficientSeekableInUriByteChannel(someContext: Context, private val uri: Uri) : InefficientSeekableInputStreamByteChannel() {
    private val applicationContext = someContext.applicationContext

    override fun calculateSize(): Long = StreamsUtil.getStreamLengthFromUri(applicationContext, uri)

    override fun getNewInputStream(): InputStream = BufferedInputStream(
            applicationContext.contentResolver.openInputStream(uri)!!)
}

Usage:

val file = ...
val uri = Uri.fromFile(file)
parseUsingInefficientSeekableInUriByteChannel(uri)
...
    private fun parseUsingInefficientSeekableInUriByteChannel(uri: Uri): Boolean {
        Log.d("AppLog", "testing using SeekableInUriByteChannel (re-creating inputStream when needed) ")
        try {
            val startTime = System.currentTimeMillis()
            ZipFile(InefficientSeekableInUriByteChannel(this, uri)).use { zipFile: ZipFile ->
                val entriesNamesAndSizes = ArrayList<Pair<String, Long>>()
                for (entry in zipFile.entries) {
                    val name = entry.name
                    val size = entry.size
                    entriesNamesAndSizes.add(Pair(name, size))
                    Log.v("Applog", "entry name: $name - ${numberFormat.format(size)}")
                }
                val endTime = System.currentTimeMillis()
                Log.d("AppLog", "got ${entriesNamesAndSizes.size} entries data. time taken: ${endTime - startTime}ms")
                return true
            }
        } catch (e: Throwable) {
            Log.e("AppLog", "error while trying to parse using SeekableInUriByteChannel:$e")
            e.printStackTrace()
        }
        return false
    }

And here's my attempt in improving it, which didn't work in some cases:

SeekableInputStreamByteChannel.kt

@RequiresApi(Build.VERSION_CODES.N)
abstract class SeekableInputStreamByteChannel : SeekableByteChannel {
    private var position: Long = 0L
    private var actualPosition: Long = 0L
    private var cachedSize: Long = -1L
    private var inputStream: InputStream? = null
    private var buffer = ByteArray(DEFAULT_BUFFER_SIZE)
    abstract fun getNewInputStream(): InputStream

    override fun isOpen(): Boolean = true

    override fun position(): Long = position

    override fun position(newPosition: Long): SeekableByteChannel {
//        Log.d("AppLog", "position $newPosition")
        require(newPosition >= 0L) { "Position has to be positive" }
        position = newPosition
        return this
    }

    open fun calculateSize(): Long {
        return getNewInputStream().use { inputStream: InputStream ->
            if (inputStream is FileInputStream)
                return inputStream.channel.size()
            var bytesCount = 0L
            while (true) {
                val available = inputStream.available()
                if (available == 0)
                    break
                val skip = inputStream.skip(available.toLong())
                if (skip < 0)
                    break
                bytesCount += skip
            }
            bytesCount
        }
    }

    final override fun size(): Long {
        if (cachedSize < 0L)
            cachedSize = calculateSize()
//        Log.d("AppLog", "size $cachedSize")
        return cachedSize
    }

    override fun close() {
        inputStream.closeSilently().also { inputStream = null }
    }

    override fun read(buf: ByteBuffer): Int {
        var wanted: Int = buf.remaining()
//        Log.d("AppLog", "read wanted:$wanted")
        if (wanted <= 0)
            return wanted
        val possible = (calculateSize() - position).toInt()
        if (possible <= 0)
            return -1
        if (wanted > possible)
            wanted = possible
        if (buffer.size < wanted)
            buffer = ByteArray(wanted)
        var inputStream = this.inputStream
        //skipping to required position
        if (inputStream == null) {
            inputStream = getNewInputStream()
//            Log.d("AppLog", "getNewInputStream")
            inputStream.skip(position)
            this.inputStream = inputStream
        } else {
            if (actualPosition > position) {
                inputStream.close()
                actualPosition = 0L
                inputStream = getNewInputStream()
//                Log.d("AppLog", "getNewInputStream")
                this.inputStream = inputStream
            }
            inputStream.skip(position - actualPosition)
        }
        //now we have an inputStream right on the needed position
        inputStream.readBytesIntoByteArray(buffer, wanted)
        buf.put(buffer, 0, wanted)
        position += wanted
        actualPosition = position
        return wanted
    }

    //not needed, because we don't store anything in memory
    override fun truncate(size: Long): SeekableByteChannel = this

    override fun write(src: ByteBuffer?): Int {
        //not needed, we read only
        throw  NotImplementedError()
    }
}

SeekableInUriByteChannel.kt

@RequiresApi(Build.VERSION_CODES.N)
class SeekableInUriByteChannel(someContext: Context, private val uri: Uri) : SeekableInputStreamByteChannel() {
    private val applicationContext = someContext.applicationContext

    override fun calculateSize(): Long = StreamsUtil.getStreamLengthFromUri(applicationContext, uri)

    override fun getNewInputStream(): InputStream = BufferedInputStream(
            applicationContext.contentResolver.openInputStream(uri)!!)
}

The questions

Is there a way to improve it?

Maybe by having as little re-creation of InputStream as possible?

Are there more possible optimizations that will let it parse ZIP files well? Maybe some caching of the data?

I ask this because it seems it's quite slow compared to other solutions I've found, and I think this could help a bit.

Body:
The skip() method of BufferedInputStream doesn't always skip all the bytes that you specify. In SeekableInputStreamByteChannel change the following code

inputStream.skip(position - actualPosition)

to

var bytesToSkip = position - actualPosition
while (bytesToSkip > 0) {
    bytesToSkip -= inputStream.skip(bytesToSkip)
}

and that should work.

Regarding making things more efficient, the first thing that ZipFile does is to zoom to the end of the file to get the central directory (CD). With the CD in hand, ZipFile knows the make up of the zip file. The zip entries should be in the same order as the files are laid out. I would read the files you want in that same order to avoid backtracking. If you can't guarantee the read order then maybe multiple input streams would make sense.


来源: stackexchange

问:
In Gerrit, how can we comment on a binary file?
In Gerrit, we can make comments attached to specific lines of a text file, but also a file-level comment about the entire file.

In the diff view, which of course shows no content for a binary file, I do not see any UI for adding a file comment.

Is there some alternative way to do that?

Could it be done through the Set Review API, for instance, using curl? How?

答:
Yes, you can add a comment in the file running the following command:

```<code>curl --request POST --user USER:PASS --data @- --header Content-Type:application/json GERRIT-SERVER/changes/CHANGE-ID/revisions/current/review <<EOF
{
    "comments": {
        "FILE-FULL-PATH": [
            {
                "message": "COMMENT"
            }
        ]
    }
}
EOF
</code>```

But it'll not possible to see the comment in the diff view, only in the change log or in the comment thread (down in the change page).

ContentLicense: CC BY-SA 4.0

Body:
Yes, you can add a comment in the file running the following command:

curl --request POST --user USER:PASS --data @- --header Content-Type:application/json GERRIT-SERVER/changes/CHANGE-ID/revisions/current/review <<EOF
{
    "comments": {
        "FILE-FULL-PATH": [
            {
                "message": "COMMENT"
            }
        ]
    }
}
EOF

But it'll not possible to see the comment in the diff view, only in the change log or in the comment thread (down in the change page).


问:
When installing JQuery, why does my "delete" link break?
I have a Rails 3 application that can create and delete products.  An index page lists all the products.  Next to each product in the list is a delete link:

```<code><%= link_to "Delete", product, :method => :delete, :title => "Delete" %>
</code>```

This looks like this in the HTML:

```<code><a href="/products/104" data-method="delete" rel="nofollow" title="Delete">Delete</a>
</code>```

This has been working fine.

I've reached the point where I want to install JQuery in my application.  I followed the steps available on several web pages (like this or this, for example).

After installing JQuery, the above "delete" link breaks.  Instead of processing the destroy action in ProductsController, Rails attempts to process the show action!

My guess is that it has something to do with the fact that web browsers can’t send DELETE requests natively, so Rails "fakes" such requests with JavaScript, which is why I had the following line before attempting the JQuery install:

```<code><%= javascript_include_tag :defaults %>
</code>```

Edit: Something during the JQuery install must have made it such that the Javascript used to "fake" the DELETE request no longer works, resulting in the show action being called.  But what exactly is happening I don't know...

Anyone have any ideas?  Thank you.

答:
Also, try including a newer version of jquery,such as 1.4.4:</p>

```<code><%= javascript_include_tag
"http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js","rails" %>
</code>```

ContentLicense: CC BY-SA 2.5

Body:
I have a Rails 3 application that can create and delete products.  An index page lists all the products.  Next to each product in the list is a delete link:

<%= link_to "Delete", product, :method => :delete, :title => "Delete" %>

This looks like this in the HTML:

Delete

This has been working fine.

I've reached the point where I want to install JQuery in my application.  I followed the steps available on several web pages (like this or this, for example).

After installing JQuery, the above "delete" link breaks.  Instead of processing the destroy action in ProductsController, Rails attempts to process the show action!

My guess is that it has something to do with the fact that web browsers can’t send DELETE requests natively, so Rails "fakes" such requests with JavaScript, which is why I had the following line before attempting the JQuery install:

<%= javascript_include_tag :defaults %>

Edit: Something during the JQuery install must have made it such that the Javascript used to "fake" the DELETE request no longer works, resulting in the show action being called.  But what exactly is happening I don't know...

Anyone have any ideas?  Thank you.

Body:
Also, try including a newer version of jquery,such as 1.4.4:

<%= javascript_include_tag
"http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js","rails" %>

ContentLicense: CC BY-SA 3.0


问:
controlM variable for YYYYMM?
I'm using ControlM and in a command, I would like to find a variable that gives me the date in this format : YYYYMM

I found there is %%$DATE variable but it gives YYYYMMDD

Thanks for you help

答:
Prefer %%$OYEAR AND %%OMONTH over %%$YEAR and %%MONTH

I suggest using the variables %%$OYEAR and %%OMONTH over %%$YEAR and %%MONTH. The reason is that date variables beginning with O refer to processing dates and do not necessarily coincide with the system date. For this case you could use any of the following options:

```<code> 1. YYYYMM = %%$OYEAR.%%OMONTH
 2. YYYYMM = %%SUBSTRING %%$ODATE 1 6
</code>```

The $ symbol preceding the variable %%$OYEAR or %%$ODATE indicates that the year is returned in 4-digit format, instead of OYEAR or ODATE which print the year with only 2 digits.

The dot (.) character is used for concatenate variables.

For example: For the order day May 29, 2020.

```<code> 1. %%$ODATE would print 20200529
 2. %%ODATE would print  200529
</code>```

Title: controlM variable for YYYYMM?

Body:
Prefer %%$OYEAR AND %%OMONTH over %%$YEAR and %%MONTH

I suggest using the variables %%$OYEAR and %%OMONTH over %%$YEAR and %%MONTH. The reason is that date variables beginning with O refer to processing dates and do not necessarily coincide with the system date. For this case you could use any of the following options:

 1. YYYYMM = %%$OYEAR.%%OMONTH
 2. YYYYMM = %%SUBSTRING %%$ODATE 1 6

The $ symbol preceding the variable %%$OYEAR or %%$ODATE indicates that the year is returned in 4-digit format, instead of OYEAR or ODATE which print the year with only 2 digits.

The dot (.) character is used for concatenate variables.

For example: For the order day May 29, 2020.

 1. %%$ODATE would print 20200529
 2. %%ODATE would print  200529


问:
How do I remove duplicates in mongodb based on multiple fields?
Here's an example of my docs:

```<code>[{name:"duplicate", value:true, id:2910921},{name:"duplicate", value:true, id:32838293},{name:"duplicate", value:false, id:3283232},{name:"notDuplicate", value:true, id:382932}]
</code>```

I want to remove if there are multiple documents that contain the same name and the same value. In the example above it would remove one document, either {name:"duplicate", value:true, id:2910921} or {name:"duplicate", value:true, id:32838293}, it does't matter to me which one.

So far, I've considered just creating a new field for each of these which would be something like newField: "duplicatetrue" and then I could just use distinct on these to remove dupes, but I am having trouble figuring out how to concat two different fields with different types into a new field. I'm definitely open to better suggestions as well. Here's what I have so far:

```<code>db.collection(collectionName).updateMany({}, {$set: {"newField": ["$name","$value"]  }})
</code>```

However, the above line doesn't output the values, rather it outputs exactly newField: ["$name","$value"]

Removing the quotes from $name and $value does not work either.

I'm using the Node mongodb driver: 3.5.8

答:
Doing it natively in node seemed to do the trick (probably not the fastest or most efficient way but the following worked):</p>

```<code>const array = await db.collection(collectionName).find({}).toArray();
const newArr = array.map((item) => {
  const newObj = Object.assign({}, item, {
    hiWorld: `${item.name}${item.amount}`,
  });
  return newObj;
});
var uniqueItems = [];
var duplicateIds = [];
newArr.forEach((item) => {
  if (uniqueItems.includes(item.hiWorld)) {
    duplicateIds.push(item._id);
  } else {
    uniqueItems.push(item.hiWorld);
  }
});

await db.collection(collectionName).deleteMany({ _id: { $in: duplicateIds } });
</code>```

Body:
Here's an example of my docs:

[{name:"duplicate", value:true, id:2910921},{name:"duplicate", value:true, id:32838293},{name:"duplicate", value:false, id:3283232},{name:"notDuplicate", value:true, id:382932}]

I want to remove if there are multiple documents that contain the same name and the same value. In the example above it would remove one document, either {name:"duplicate", value:true, id:2910921} or {name:"duplicate", value:true, id:32838293}, it does't matter to me which one.

So far, I've considered just creating a new field for each of these which would be something like newField: "duplicatetrue" and then I could just use distinct on these to remove dupes, but I am having trouble figuring out how to concat two different fields with different types into a new field. I'm definitely open to better suggestions as well. Here's what I have so far:

db.collection(collectionName).updateMany({}, {$set: {"newField": ["$name","$value"]  }})

However, the above line doesn't output the values, rather it outputs exactly newField: ["$name","$value"]

Removing the quotes from $name and $value does not work either.

I'm using the Node mongodb driver: 3.5.8

Body:
Doing it natively in node seemed to do the trick (probably not the fastest or most efficient way but the following worked):

const array = await db.collection(collectionName).find({}).toArray();
const newArr = array.map((item) => {
  const newObj = Object.assign({}, item, {
    hiWorld: `${item.name}${item.amount}`,
  });
  return newObj;
});
var uniqueItems = [];
var duplicateIds = [];
newArr.forEach((item) => {
  if (uniqueItems.includes(item.hiWorld)) {
    duplicateIds.push(item._id);
  } else {
    uniqueItems.push(item.hiWorld);
  }
});

await db.collection(collectionName).deleteMany({ _id: { $in: duplicateIds } });


问:
Problem with conditional inside while loop
i'm doing exercise 7-4 from "Python Crash Course", which is about writing a while loop to prompt customers to input pizza toppings until they type "quit". While i'm running the following code it prints once every third time and breaks after typing "quit" twice. Can someone please point out what i'm doing wrong. Thank you.

```<code>prompt = "Enter your topping: "

while True:
  topping = input(prompt)
  if input(prompt) == "quit":
    break
  else:
    print(f"{input(prompt)} is added")
</code>```

Here is an example of it running:

```<code>>>> Enter your topping: pepperoni
>>> Enter your topping: pepperoni
>>> Enter your topping: cheese
cheese is added
>>> Enter your topping: quit
>>> Enter your topping: quit
</code>```

答:
You're asking for input twice. First time, you store the value in topping, and you never do anything with it again.

Then, you ask for input again, after the "if" in if input(prompt), and then you do something based on what it returns and tests against "quit".

You should be doing something with the topping variable instead of asking again. Since you're learning, I am not going to tell you what to do.

The bigger thing you need to understand is that function calls do something. That topping = input(prompt) is not like a mathematical expression of equality where you can thus substitute input(prompt) for all the places you mean topping. The topping represents some constant value in the form of an object. The prompt() is a set of instructions that the interpreter is going to go do and put the result of those instructions in place in the code. That "=" is not an equality assertion. It's an assignment of one value to a name.

Body:
i'm doing exercise 7-4 from "Python Crash Course", which is about writing a while loop to prompt customers to input pizza toppings until they type "quit". While i'm running the following code it prints once every third time and breaks after typing "quit" twice. Can someone please point out what i'm doing wrong. Thank you.

prompt = "Enter your topping: "

while True:
  topping = input(prompt)
  if input(prompt) == "quit":
    break
  else:
    print(f"{input(prompt)} is added")

Here is an example of it running:

>>> Enter your topping: pepperoni
>>> Enter your topping: pepperoni
>>> Enter your topping: cheese
cheese is added
>>> Enter your topping: quit
>>> Enter your topping: quit


问:
Know the trigger when user has pressed cancel buttons during In-App purchase
I have integrated IAP functionality in my flutter app. I wants to know when user has clicked the "Cancel" button on IAP popup.
There are many solution found here but that all code is in native.
It will be very helpful If I get the trigger of cancel button click in flutter iOS.
On the cancel button click I need to do other functionalities.

I have followed the IAP integration code from this link:
https://fireship.io/lessons/flutter-inapp-purchases/
and the IAP popup is shown as default popup not a custom.

Please give some suggestion. Any help would be appreciated.
Thank you.

答:
I created a loop to look for failed transactions and then finish them accordingly.

I am still experimenting with where to do this to try to avoid a user error. I am also going to try to do a similar process in the stream listener that processes purchases.

There are StoreKit Wrappers included with IAP plugin:

Note: I looked at SK info for XCode and it seems fine to do this with a failed transaction. They said it is a 'no no' to do it to a pending one.

```<code>  Future<Null> _removeFailedPendingPurchases() async {
debugPrint(':::: SWIPE WAR ::::: _removeFailedPendingPurchases()');
final SKPaymentQueueWrapper paymentWrapper = SKPaymentQueueWrapper();
final List<SKPaymentTransactionWrapper> transactions =
    await paymentWrapper.transactions();
debugPrint(
    ':::: SWIPE WAR ::::: transactions ${transactions.length} ${transactions.toString()}');

for (SKPaymentTransactionWrapper transaction in transactions) {
  debugPrint('TRANSACTION everything : ${transaction.toString()}');
  debugPrint('TRANSACTION STATE : ${transaction.transactionState}');
  if (transaction.transactionState ==
      SKPaymentTransactionStateWrapper.failed)
    await paymentWrapper.finishTransaction(transaction);
}

return;
</code>```

}

Body:
I created a loop to look for failed transactions and then finish them accordingly.

I am still experimenting with where to do this to try to avoid a user error. I am also going to try to do a similar process in the stream listener that processes purchases.

There are StoreKit Wrappers included with IAP plugin:

Note: I looked at SK info for XCode and it seems fine to do this with a failed transaction. They said it is a 'no no' to do it to a pending one.

  Future<Null> _removeFailedPendingPurchases() async {
debugPrint(':::: SWIPE WAR ::::: _removeFailedPendingPurchases()');
final SKPaymentQueueWrapper paymentWrapper = SKPaymentQueueWrapper();
final List<SKPaymentTransactionWrapper> transactions =
    await paymentWrapper.transactions();
debugPrint(
    ':::: SWIPE WAR ::::: transactions ${transactions.length} ${transactions.toString()}');

for (SKPaymentTransactionWrapper transaction in transactions) {
  debugPrint('TRANSACTION everything : ${transaction.toString()}');
  debugPrint('TRANSACTION STATE : ${transaction.transactionState}');
  if (transaction.transactionState ==
      SKPaymentTransactionStateWrapper.failed)
    await paymentWrapper.finishTransaction(transaction);
}

return;

}


问:
C# .NET RichTextBox GetCharOffsetFromPosition?
Is there a way to get character offset from a position?

I have a box that looks like this -

I want to parse it character by character but I want to detect when it is superscript (which I achieved by setting SelectionCharOffset to 10

What I have is a loop that looks like this so I can acces the position with i

```<code>for (int i = 0; i < Text1.TextLength; i++) {
     //I can use things here like Text1.Text[i]...
}
</code>```

答:
The same way you achieved superscript.

Use the SelectionCharOffset property (along with SelectionStart and SelectionLength to select one character at a time) and see if its a positive number (since positive represents superscript and negative represents subscript).

```<code>for (int i = 0; i < Text1.TextLength; i++)
{
    Text1.SelectionStart = i;
    Text1.SelectionLength = 1;

    if (Text1.SelectionCharOffset > 0)
    {
        ...
    }
}
</code>```

Body:
Is there a way to get character offset from a position?

I have a box that looks like this -

I want to parse it character by character but I want to detect when it is superscript (which I achieved by setting SelectionCharOffset to 10

What I have is a loop that looks like this so I can acces the position with i

for (int i = 0; i < Text1.TextLength; i++) {
     //I can use things here like Text1.Text[i]...
}

Body:
The same way you achieved superscript.

Use the SelectionCharOffset property (along with SelectionStart and SelectionLength to select one character at a time) and see if its a positive number (since positive represents superscript and negative represents subscript).

for (int i = 0; i < Text1.TextLength; i++)
{
    Text1.SelectionStart = i;
    Text1.SelectionLength = 1;

    if (Text1.SelectionCharOffset > 0)
    {
        ...
    }
}


问:
Can ConcurrentDictionary.GetOrAdd() be called recursively?
ConcurrentDictionary.GetOrAdd(TKey, Func<TKey, TValue>) accepts a factory function to allow lazy instantiation of the item to be put into the dictionary.

Is it safe to define a factory function that itself calls GetOrAdd(), i.e. GetOrAdd is being called within the context of a 'parent' GetOrAdd().

The following code demonstrates the pattern; It does appear to work, but is it safe?

```<code>class Program
{
    static ConcurrentDictionary<string,object> __dict = new ConcurrentDictionary<string, object>();

    static void Main(string[] args)
    {
        Foo foo = GetOrAddFoo();
        Console.WriteLine(foo._name);
        Console.WriteLine(foo._bar._name);
        Console.ReadKey();
    }

    static Bar GetOrAddBar()
    {
        Console.WriteLine("GetOrAddBar: enter");
        Func<string,Bar> factoryFn = (x) => LoadBar(x);
        Bar bar = __dict.GetOrAdd("bar", factoryFn) as Bar;
        Console.WriteLine("GetOrAddBar: exit");
        return bar;
    }

    static Foo GetOrAddFoo()
    {
        Console.WriteLine("GetOrAddFoo: enter");
        Func<string,Foo> factoryFn = (x) => LoadFoo(x);
        Foo foo = __dict.GetOrAdd("foo", factoryFn) as Foo;
        Console.WriteLine("GetOrAddFoo: exit");
        return foo;
    }

    static Bar LoadBar(string name)
    {
        Bar bar =  new Bar();
        bar._name = name;
        return bar;
    }

    static Foo LoadFoo(string name)
    {
        Foo foo = new Foo();
        foo._name = name;
        foo._bar = GetOrAddBar();
        return foo;
    }

    public class Foo
    {
       public string _name;
       public Bar _bar;
    }

    public class Bar
    {
        public string _name;
    }
}
</code>```

答:
The answer is yes, it is perfectly safe. The value functions are only called if the given key does not exist yet. Below is a walkthrough of what happens under the hood.

Walkthrough

First we assume the dictionary is completely empty, which I'll only show the keys in an array format for simplicity:

```<code>dictionary = []
</code>```

On an initial first time execution of the GetOrAddFoo method, the "Foo" key does not exist so the dictionary invokes the value function, which in this invocation is the LoadFoo method. The dictionary is still empty here.

```<code>dictionary = []
</code>```

LoadFoo internally calls GetOrAddBar, which checks and finds that the "Bar" key does not exist, so the LoadBar value function is invoked and it returns with the created "Bar" entry. The dictionary at this point looks like this:

```<code>dictionary = ["Bar"]
</code>```

The dictionary at this point contains the item "Bar" in it. We have not yet completed the LoadFoo value function, but it will now.

```<code>dictionary = ["Bar"]
</code>```

The LoadFoo method regains control and returns a Foo object to be stored in the dictionary. After LoadFoo completes, GetOrAddFoo can complete too. We now have the dictionary looking like this:

```<code>dictionary = ["Bar", "Foo"]
</code>```

Future Calls of GetOrAddFoo

On subsequent calls to GetOrAddFoo, the dictionary already has an entry for Foo and thus will not invoke its value function, or even the Bar value function either. It returns immediately.

```<code>dictionary = ["Bar", "Foo"]
</code>```

But what happens if we remove Bar from the dictionary and then call GetOrAddFoo? Say that we do remove it, leaving our dictionary like this:

```<code>dictionary = ["Foo"]
</code>```

And now we call GetOrAddFoo again. Foo still exists, so the dictionary will not call the LoadFoo value function. And thus, Bar is not re-added to the dictionary. Our dictionary remains the same:

```<code>dictionary = ["Foo"]
</code>```

If we call GetOrAddBar directly though, we'll get "Bar" added back in then.

```<code>dictionary = ["Foo", "Bar"]
</code>```

Under the hood of the Concurrent Dictionary's Get-Or-Add method

Under the hood, anytime the GetOrAdd method is called, the existence of the given key is checked first.

If it does NOT exist at that point, the value function is then invoked. AFTER the value function returns, a lock is placed on the dictionary to allow the new entry to be added.

In a multi-threaded world, we could have 2 threads trying to add the same exact key to the dictionary. The dictionary would run the value function, then try to acquire the lock, and after getting a lock, check if the key exists again.

The reason for this is on lock retrieval, another thread could jump in and add the same key. The original thread would need to check for this scenario once it receives the lock, so that it doesn't end up causing a key collision.

Body:
ConcurrentDictionary.GetOrAdd(TKey, Func<TKey, TValue>) accepts a factory function to allow lazy instantiation of the item to be put into the dictionary.

Is it safe to define a factory function that itself calls GetOrAdd(), i.e. GetOrAdd is being called within the context of a 'parent' GetOrAdd().

The following code demonstrates the pattern; It does appear to work, but is it safe?

class Program
{
    static ConcurrentDictionary<string,object> __dict = new ConcurrentDictionary<string, object>();

    static void Main(string[] args)
    {
        Foo foo = GetOrAddFoo();
        Console.WriteLine(foo._name);
        Console.WriteLine(foo._bar._name);
        Console.ReadKey();
    }

    static Bar GetOrAddBar()
    {
        Console.WriteLine("GetOrAddBar: enter");
        Func<string,Bar> factoryFn = (x) => LoadBar(x);
        Bar bar = __dict.GetOrAdd("bar", factoryFn) as Bar;
        Console.WriteLine("GetOrAddBar: exit");
        return bar;
    }

    static Foo GetOrAddFoo()
    {
        Console.WriteLine("GetOrAddFoo: enter");
        Func<string,Foo> factoryFn = (x) => LoadFoo(x);
        Foo foo = __dict.GetOrAdd("foo", factoryFn) as Foo;
        Console.WriteLine("GetOrAddFoo: exit");
        return foo;
    }

    static Bar LoadBar(string name)
    {
        Bar bar =  new Bar();
        bar._name = name;
        return bar;
    }

    static Foo LoadFoo(string name)
    {
        Foo foo = new Foo();
        foo._name = name;
        foo._bar = GetOrAddBar();
        return foo;
    }

    public class Foo
    {
       public string _name;
       public Bar _bar;
    }

    public class Bar
    {
        public string _name;
    }
}

Body:
The answer is yes, it is perfectly safe. The value functions are only called if the given key does not exist yet. Below is a walkthrough of what happens under the hood.

Walkthrough

First we assume the dictionary is completely empty, which I'll only show the keys in an array format for simplicity:

dictionary = []

On an initial first time execution of the GetOrAddFoo method, the "Foo" key does not exist so the dictionary invokes the value function, which in this invocation is the LoadFoo method. The dictionary is still empty here.

dictionary = []

LoadFoo internally calls GetOrAddBar, which checks and finds that the "Bar" key does not exist, so the LoadBar value function is invoked and it returns with the created "Bar" entry. The dictionary at this point looks like this:

dictionary = ["Bar"]

The dictionary at this point contains the item "Bar" in it. We have not yet completed the LoadFoo value function, but it will now.

dictionary = ["Bar"]

The LoadFoo method regains control and returns a Foo object to be stored in the dictionary. After LoadFoo completes, GetOrAddFoo can complete too. We now have the dictionary looking like this:

dictionary = ["Bar", "Foo"]

Future Calls of GetOrAddFoo

On subsequent calls to GetOrAddFoo, the dictionary already has an entry for Foo and thus will not invoke its value function, or even the Bar value function either. It returns immediately.

dictionary = ["Bar", "Foo"]

But what happens if we remove Bar from the dictionary and then call GetOrAddFoo? Say that we do remove it, leaving our dictionary like this:

dictionary = ["Foo"]

And now we call GetOrAddFoo again. Foo still exists, so the dictionary will not call the LoadFoo value function. And thus, Bar is not re-added to the dictionary. Our dictionary remains the same:

dictionary = ["Foo"]

If we call GetOrAddBar directly though, we'll get "Bar" added back in then.

dictionary = ["Foo", "Bar"]

Under the hood of the Concurrent Dictionary's Get-Or-Add method

Under the hood, anytime the GetOrAdd method is called, the existence of the given key is checked first.

If it does NOT exist at that point, the value function is then invoked. AFTER the value function returns, a lock is placed on the dictionary to allow the new entry to be added.

In a multi-threaded world, we could have 2 threads trying to add the same exact key to the dictionary. The dictionary would run the value function, then try to acquire the lock, and after getting a lock, check if the key exists again.

The reason for this is on lock retrieval, another thread could jump in and add the same key. The original thread would need to check for this scenario once it receives the lock, so that it doesn't end up causing a key collision.


问:
In ipython, how can I type multiple lines before it interpret what I wrote?
In ipython, sometimes I want to type multiple lines and be able to go back in history and call it again. The problem is that it execute right upon pressing return. I am using \ before pressing return, but need to remove it.

答:
I had the idea of creating an empty with so my statements are in a block. Yeah, but what is an empty with ???

noop! So here's my noop:

#!/usr/bin/python
# noop to use in with statement, so that ipython does not execute uppon pressing enter.

class noop(object):
    def __enter__(self):
        pass
    def __exit__(self, exc_type, exc_val, exc_tb):
        pass
```

<p>You can place it in <code>~/.ipython/profile_default/startup/noop.py</code> to let you use it directly, like so:</p>

<pre class="lang-py prettyprint-override"><code>with noop():
    x=None
    print(x)
</code>```

It would be great to have two typing modes. Changing mode for an empty line, and have the prompt reflect this state

Body:
I had the idea of creating an empty with so my statements are in a block. Yeah, but what is an empty with ???

noop! So here's my noop:

#!/usr/bin/python
# noop to use in with statement, so that ipython does not execute uppon pressing enter.

class noop(object):
    def __enter__(self):
        pass
    def __exit__(self, exc_type, exc_val, exc_tb):
        pass

You can place it in ~/.ipython/profile_default/startup/noop.py to let you use it directly, like so:

with noop():
    x=None
    print(x)

It would be great to have two typing modes. Changing mode for an empty line, and have the prompt reflect this state


问:
how to constrain size of youtube embed iframe size?
The youtube embed code's general structure is like this:

I want users to upload this code to my SQL table and then I will retrieve and output all the embed codes from the SQL table. The problem is that I have no choice as to what width or height the iframe is going to be since the users are making the embed codes through youtube's site.

Let's say I have 20 instances of the code I posted above and I want to auto-resize all the iframes to 640 x 480 when they get retrieved. How do I do this?

答:
first, use substr function with strpos to grab and save 3 things in you database:

youtube id

width

height

second, use substr_replace function to change the value of all instances depending on your needs


问:
How to prevent unnecessary renders in a Component using useContext?
I would like to know how can I avoid unnecessary updates on a child component that does not receive props, but uses useContext.

I've added React.memo to the Child2 component for me to make some demo tests.

As you can see, when I change the input value which uses context to pass the data to child1, Child2 does not re-render, as React.memo prevents this behavior.

How can I prevent unnecessary renders in Child1 as well? I know that React.memo won't work as it needs props, and with context this will not happen, as no props are being passed down to this component

App.js

```<code>import React, {useState} from 'react';
import './App.css';
import Child1 from "./Child1";
import Child2 from "./Child2";
import SillyContext from './context'

function App() {
    const [name, setName] = useState('Radha');
    const [count, setCount] = useState(0)

    const increaseCount = () => {
        setCount(prevState => prevState + 1)
    }

    return (
        <div className="App">
            <Child2 count={count}/>
            <button onClick={increaseCount}>Increase</button>
            <input type="text" value={name} onChange={(event => setName(event.target.value))}/>
            <SillyContext.Provider value={{name}}>
                <Child1/>
            </SillyContext.Provider>
        </div>
    );
}

export default App;
</code>```

Child1

```<code>import React, {useContext} from "react";
import SillyContext from './context'

export default function Child1() {
    const sillyContext = useContext(SillyContext)
    console.log('[Child 1 ran]')
    return (
        <div>
            <div>[Child 1]: {sillyContext.name}</div>
        </div>
    )
}
</code>```

Child2

```<code>import React from 'react'

export default React.memo(function Child2(props) {
    console.log('[Child2 Ran!]')
    return <div>[Child2] - Count: {props.count}</div>
})
</code>```

答:
The major problem due to which Child1 re-renders when count is updated is because you are passing a new object reference to Context Provider everytime.

Also If the App component re-renders, all element rendered within it re-render, unless they implement memoization or are PureComponent or use shouldComponentUpdate

You can make 2 changes to fix your re-rendering

wrap Child1 with React.memo

Use useMemo to memoize the object passed as value to provider

App.js

```<code>function App() {
  const [name, setName] = useState("Radha");
  const [count, setCount] = useState(0);

  const increaseCount = () => {
    setCount(prevState => prevState + 1);
  };

  const value = useMemo(() => ({ name }), [name]);
  return (
    <div className="App">
      <Child2 count={count} />
      <button onClick={increaseCount}>Increase</button>

      <input
        type="text"
        value={name}
        onChange={event => setName(event.target.value)}
      />
      <SillyContext.Provider value={value}>
        <Child1 />
      </SillyContext.Provider>
    </div>
  );
}
</code>```

Child2

```<code>const Child2 = React.memo(function(props) {
  console.log("[Child2 Ran!]");
  return <div>[Child2] - Count: {props.count}</div>;
});
</code>```

Child 1

```<code>const Child1 = React.memo(function() {
  const sillyContext = useContext(SillyContext);
  console.log("[Child 1 ran]");
  return (
    <div>
      <div>[Child 1]: {sillyContext.name}</div>
    </div>
  );
});
</code>```

Working demo

Body:
I would like to know how can I avoid unnecessary updates on a child component that does not receive props, but uses useContext.

I've added React.memo to the Child2 component for me to make some demo tests.

As you can see, when I change the input value which uses context to pass the data to child1, Child2 does not re-render, as React.memo prevents this behavior.

How can I prevent unnecessary renders in Child1 as well? I know that React.memo won't work as it needs props, and with context this will not happen, as no props are being passed down to this component

App.js

import React, {useState} from 'react';
import './App.css';
import Child1 from "./Child1";
import Child2 from "./Child2";
import SillyContext from './context'

function App() {
    const [name, setName] = useState('Radha');
    const [count, setCount] = useState(0)

    const increaseCount = () => {
        setCount(prevState => prevState + 1)
    }

    return (

            <Child2 count={count}/>
            <button onClick={increaseCount}>Increase</button>
            <input type="text" value={name} onChange={(event => setName(event.target.value))}/>
            <SillyContext.Provider value={{name}}>
                <Child1/>
            </SillyContext.Provider>

    );
}

export default App;

Child1

import React, {useContext} from "react";
import SillyContext from './context'

export default function Child1() {
    const sillyContext = useContext(SillyContext)
    console.log('[Child 1 ran]')
    return (

[Child 1]: {sillyContext.name}

    )
}

Child2

import React from 'react'

export default React.memo(function Child2(props) {
    console.log('[Child2 Ran!]')
    return
[Child2] - Count: {props.count}

})

Body:
The major problem due to which Child1 re-renders when count is updated is because you are passing a new object reference to Context Provider everytime.

Also If the App component re-renders, all element rendered within it re-render, unless they implement memoization or are PureComponent or use shouldComponentUpdate

You can make 2 changes to fix your re-rendering

wrap Child1 with React.memo

Use useMemo to memoize the object passed as value to provider

App.js

function App() {
  const [name, setName] = useState("Radha");
  const [count, setCount] = useState(0);

  const increaseCount = () => {
    setCount(prevState => prevState + 1);
  };

  const value = useMemo(() => ({ name }), [name]);
  return (
    <div className="App">
      <Child2 count={count} />
      <button onClick={increaseCount}>Increase</button>

      <input
        type="text"
        value={name}
        onChange={event => setName(event.target.value)}
      />
      <SillyContext.Provider value={value}>
        <Child1 />
      </SillyContext.Provider>
    </div>
  );
}

Child2

const Child2 = React.memo(function(props) {
  console.log("[Child2 Ran!]");
  return <div>[Child2] - Count: {props.count}</div>;
});

Child 1

const Child1 = React.memo(function() {
  const sillyContext = useContext(SillyContext);
  console.log("[Child 1 ran]");
  return (
    <div>
      <div>[Child 1]: {sillyContext.name}</div>
    </div>
  );
});

Working demo


问:
Error: Invalid hook call. But can't understand where. React JS
It's my firt time on react, and I'm trying to build a sign up form with steps. I read the documentation on material-ui and about ReactJS, but can't understand where I do mistakes.

I'll paste the error:
"Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See link for tips about how to debug and fix this problem."

I think the error is in this two classes, but can't understand why or where.

FormUtentiPersonali.js

```<code>import React, { Component } from 'react';
import TextField from '@material-ui/core/TextField';
import { makeStyles } from '@material-ui/core/styles';
import Button from '@material-ui/core/Button';

    const useStyles=makeStyles((theme)=>({
        root: {
            '& .MuiTextField-root': {
              margin: theme.spacing(1),
              width: '25ch',
            },
        },
    }));

export class FormUtentiPersonali extends Component {
    continue = e =>{
        e.preventDefault();
        this.props.nextStep();
    };
    back = e =>{
        e.preventDefault();
        this.props.prevStep();
    };
    render() {
        //const classes = useStyles();
        const {values,handleChange}=this.props;
        return (
            <form noValidate autoComplete="off">
                <TextField
                required
                id="email-utente"
                label="E-mail"
                defaultValue={values.email}
                onChange={handleChange('email')}
                 />
                 <br/>
                 <TextField
                required
                id="password-utente"
                label="Imposta password"
                defaultValue={values.password}
                onChange={handleChange('password')}
                type="password"
                 />
                 <br/>
                 <TextField
                required
                id="conferma-password-utente"
                label="Conferma password"
                defaultValue={values.confermaPassword}
                onChange={handleChange('confermaPassword')}
                type="password"
                 />
                 <Button
                        label="Indietro"
                        variant="contained"
                        onClick={this.back}
                    >
                        Indietro
                        </Button>

                    <Button
                        label="Continua"
                        color="secondary"
                        variant="contained"
                        onClick={this.continue}
                    >
                        Continua
                        </Button>
            </form>
        );
    }
}

export default FormUtentiPersonali;

</code>```

FormUtentiAnagrafica.js

```<code>import React, { Component } from 'react';
import TextField from '@material-ui/core/TextField';
import { makeStyles } from '@material-ui/core/styles';
import MenuItem from '@material-ui/core/MenuItem';
import Button from '@material-ui/core/Button';

    const useStyles=makeStyles((theme)=>({
        root: {
            '& .MuiTextField-root': {
              margin: theme.spacing(1),
              width: '25ch',
            },
        },
    }));

export class FormUtenteAnagrafica extends Component {
    continue = e =>{
        e.preventDefault();
        this.props.nextStep();
    };

    render() {
        const giorni=[
            {
                value:'01',
                label:'01',
            },
            {
                value:'02',
                label:'02',
            },
            {
                value:'03',
                label:'03',
            },
            {
                value:'04',
                label:'04',
            },
            {
                value:'05',
                label:'05',
            },
            {
                value:'06',
                label:'06',
            },
            {
                value:'07',
                label:'07',
            },
            {
                value:'08',
                label:'08',
            },
            {
                value:'09',
                label:'09',
            },
            {
                value:'10',
                label:'10',
            },
            {
                value:'11',
                label:'11',
            },
            {
                value:'12',
                label:'12',
            },
            {
                value:'13',
                label:'13',
            },
            {
                value:'14',
                label:'14',
            },
            {
                value:'15',
                label:'15',
            },
            {
                value:'16',
                label:'16',
            },
            {
                value:'17',
                label:'17',
            },
            {
                value:'18',
                label:'18',
            },
            {
                value:'19',
                label:'19',
            },
            {
                value:'20',
                label:'20',
            },
            {
                value:'21',
                label:'21',
            },
            {
                value:'22',
                label:'22',
            },
            {
                value:'23',
                label:'23',
            },
            {
                value:'24',
                label:'24',
            },
            {
                value:'25',
                label:'25',
            },
            {
                value:'26',
                label:'26',
            },
            {
                value:'27',
                label:'27',
            },
            {
                value:'28',
                label:'28',
            },
            {
                value:'29',
                label:'29',
            },
            {
                value:'30',
                label:'30',
            },
            {
                value:'31',
                label:'31',
            },
        ];
        const mesi=[
            {
                value: 'Gen',
                label: 'Gen',
            },
            {
                value: 'Feb',
                label: 'Feb',
            },
            {
                value: 'Mar',
                label: 'Mar',
            },
            {
                value: 'Apr',
                label: 'Apr',
            },
            {
                value: 'Mag',
                label: 'Mag',
            },
            {
                value: 'Giu',
                label: 'Giu',
            },
            {
                value: 'Lug',
                label: 'Lug',
            },
            {
                value: 'Ago',
                label: 'Ago',
            },
            {
                value: 'Set',
                label: 'Set',
            },
            {
                value: 'Ott',
                label: 'Ott',
            },
            {
                value: 'Nov',
                label: 'Nov',
            },
            {
                value: 'Dic',
                label: 'Dic',
            },
        ]

        const {values,handleChange}=this.props;
        //const classes=useStyles();
        const [giorno,setGiorno]=React.useState('01');
        const [mese,setMese]=React.useState('Gen');
        const cambiaGiorno=event=>{
            setGiorno(event.target.value);
        };
        const cambiaMese=event=>{
            setMese(event.target.value);
        }
        return (
            <form noValidate autoComplete="off">
                <TextField
                required
                id="nome-utente"
                label="Inserisci nome"
                onChange={handleChange('nome')}
                defaultValue={values.nome}
                />
                <br/>
                <TextField
                required
                id="cognnome-utente"
                label="Inserisci cognome"
                onChange={handleChange('cognome')}
                defaultValue={values.cognome}
                />
                <br/>
                <TextField
                required
                id="numero-telefono-utente"
                label="Numero di telefono"
                onChange={handleChange('numeroDiTelefono')}
                defaultValue={values.numeroDiTelefono}
                />
                <br/>
                <TextField
                required
                id="giorno-nascita-utente"
                label="Giorno di nascita"
                value={giorno}
                onChange={handleChange('birthdayDay')}
                onChange={cambiaGiorno}
                >
                {giorni.map((option) => (
            <MenuItem key={option.value} value={option.value}>
              {option.label}
            </MenuItem>
          ))}
          </TextField>

          <TextField
                required
                id="mese-nascita-utente"
                label="Mese di nascita"
                value={mese}
                onChange={handleChange('birthdayMonth')}
                onChange={cambiaMese}
                >
                {mesi.map((option) => (
            <MenuItem key={option.value} value={option.value}>
              {option.label}
            </MenuItem>
          ))}
          </TextField>
          <br/>
          <TextField
          id="anno-nascita-utente"
          label="Anno di nascita"
          type="number"
          InputLabelProps={{
            shrink: true,
          }}
          onChange={handleChange('birthdayYear')}
          defaultValue={values.birthdayYear}
        />
        <br/>
        <Button
            label="Continua"
            color="secondary"
            variant="contained"
            onClick={this.continue}
        >
            Continua
        </Button>
        </form>
        );
    }
}

export default FormUtenteAnagrafica;
</code>```

答:
useState is a React hook which planned for functional components and you are creating Class components, So you can determine your state somewhere like constructor method. e.g:

class MyComponent extends React.Component {
   constructor() {
     super();

     this.state = {
       myVar1: myValue,
       myVar2: {id:1, title:'foo'}
     }
   }
   // ...
}
```

<p>Then you can change your variables using <code>setState</code> method which inherits from <code>Component</code> class like this:</p>

```  <Button onClick={()=>this.setState({myVar: 'myValue'})} />
```

Please study first.

Body:
It's my firt time on react, and I'm trying to build a sign up form with steps. I read the documentation on material-ui and about ReactJS, but can't understand where I do mistakes.

I'll paste the error:
"Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See link for tips about how to debug and fix this problem."

I think the error is in this two classes, but can't understand why or where.

FormUtentiPersonali.js

import React, { Component } from 'react';
import TextField from '@material-ui/core/TextField';
import { makeStyles } from '@material-ui/core/styles';
import Button from '@material-ui/core/Button';

    const useStyles=makeStyles((theme)=>({
        root: {
            '& .MuiTextField-root': {
              margin: theme.spacing(1),
              width: '25ch',
            },
        },
    }));

export class FormUtentiPersonali extends Component {
    continue = e =>{
        e.preventDefault();
        this.props.nextStep();
    };
    back = e =>{
        e.preventDefault();
        this.props.prevStep();
    };
    render() {
        //const classes = useStyles();
        const {values,handleChange}=this.props;
        return (
            <form noValidate autoComplete="off">
                <TextField
                required
                id="email-utente"
                label="E-mail"
                defaultValue={values.email}
                onChange={handleChange('email')}
                 />

                 <TextField
                required
                id="password-utente"
                label="Imposta password"
                defaultValue={values.password}
                onChange={handleChange('password')}
                type="password"
                 />

                 <TextField
                required
                id="conferma-password-utente"
                label="Conferma password"
                defaultValue={values.confermaPassword}
                onChange={handleChange('confermaPassword')}
                type="password"
                 />
                 <Button
                        label="Indietro"
                        variant="contained"
                        onClick={this.back}
                    >
                        Indietro
                        </Button>

                    <Button
                        label="Continua"
                        color="secondary"
                        variant="contained"
                        onClick={this.continue}
                    >
                        Continua
                        </Button>
            </form>
        );
    }
}

export default FormUtentiPersonali;

FormUtentiAnagrafica.js

import React, { Component } from 'react';
import TextField from '@material-ui/core/TextField';
import { makeStyles } from '@material-ui/core/styles';
import MenuItem from '@material-ui/core/MenuItem';
import Button from '@material-ui/core/Button';

    const useStyles=makeStyles((theme)=>({
        root: {
            '& .MuiTextField-root': {
              margin: theme.spacing(1),
              width: '25ch',
            },
        },
    }));

export class FormUtenteAnagrafica extends Component {
    continue = e =>{
        e.preventDefault();
        this.props.nextStep();
    };

    render() {
        const giorni=[
            {
                value:'01',
                label:'01',
            },
            {
                value:'02',
                label:'02',
            },
            {
                value:'03',
                label:'03',
            },
            {
                value:'04',
                label:'04',
            },
            {
                value:'05',
                label:'05',
            },
            {
                value:'06',
                label:'06',
            },
            {
                value:'07',
                label:'07',
            },
            {
                value:'08',
                label:'08',
            },
            {
                value:'09',
                label:'09',
            },
            {
                value:'10',
                label:'10',
            },
            {
                value:'11',
                label:'11',
            },
            {
                value:'12',
                label:'12',
            },
            {
                value:'13',
                label:'13',
            },
            {
                value:'14',
                label:'14',
            },
            {
                value:'15',
                label:'15',
            },
            {
                value:'16',
                label:'16',
            },
            {
                value:'17',
                label:'17',
            },
            {
                value:'18',
                label:'18',
            },
            {
                value:'19',
                label:'19',
            },
            {
                value:'20',
                label:'20',
            },
            {
                value:'21',
                label:'21',
            },
            {
                value:'22',
                label:'22',
            },
            {
                value:'23',
                label:'23',
            },
            {
                value:'24',
                label:'24',
            },
            {
                value:'25',
                label:'25',
            },
            {
                value:'26',
                label:'26',
            },
            {
                value:'27',
                label:'27',
            },
            {
                value:'28',
                label:'28',
            },
            {
                value:'29',
                label:'29',
            },
            {
                value:'30',
                label:'30',
            },
            {
                value:'31',
                label:'31',
            },
        ];
        const mesi=[
            {
                value: 'Gen',
                label: 'Gen',
            },
            {
                value: 'Feb',
                label: 'Feb',
            },
            {
                value: 'Mar',
                label: 'Mar',
            },
            {
                value: 'Apr',
                label: 'Apr',
            },
            {
                value: 'Mag',
                label: 'Mag',
            },
            {
                value: 'Giu',
                label: 'Giu',
            },
            {
                value: 'Lug',
                label: 'Lug',
            },
            {
                value: 'Ago',
                label: 'Ago',
            },
            {
                value: 'Set',
                label: 'Set',
            },
            {
                value: 'Ott',
                label: 'Ott',
            },
            {
                value: 'Nov',
                label: 'Nov',
            },
            {
                value: 'Dic',
                label: 'Dic',
            },
        ]

        const {values,handleChange}=this.props;
        //const classes=useStyles();
        const [giorno,setGiorno]=React.useState('01');
        const [mese,setMese]=React.useState('Gen');
        const cambiaGiorno=event=>{
            setGiorno(event.target.value);
        };
        const cambiaMese=event=>{
            setMese(event.target.value);
        }
        return (
            <form noValidate autoComplete="off">
                <TextField
                required
                id="nome-utente"
                label="Inserisci nome"
                onChange={handleChange('nome')}
                defaultValue={values.nome}
                />

                <TextField
                required
                id="cognnome-utente"
                label="Inserisci cognome"
                onChange={handleChange('cognome')}
                defaultValue={values.cognome}
                />

                <TextField
                required
                id="numero-telefono-utente"
                label="Numero di telefono"
                onChange={handleChange('numeroDiTelefono')}
                defaultValue={values.numeroDiTelefono}
                />

                <TextField
                required
                id="giorno-nascita-utente"
                label="Giorno di nascita"
                value={giorno}
                onChange={handleChange('birthdayDay')}
                onChange={cambiaGiorno}
                >
                {giorni.map((option) => (
            <MenuItem key={option.value} value={option.value}>
              {option.label}
            </MenuItem>
          ))}
          </TextField>

          <TextField
                required
                id="mese-nascita-utente"
                label="Mese di nascita"
                value={mese}
                onChange={handleChange('birthdayMonth')}
                onChange={cambiaMese}
                >
                {mesi.map((option) => (
            <MenuItem key={option.value} value={option.value}>
              {option.label}
            </MenuItem>
          ))}
          </TextField>

          <TextField
          id="anno-nascita-utente"
          label="Anno di nascita"
          type="number"
          InputLabelProps={{
            shrink: true,
          }}
          onChange={handleChange('birthdayYear')}
          defaultValue={values.birthdayYear}
        />

        <Button
            label="Continua"
            color="secondary"
            variant="contained"
            onClick={this.continue}
        >
            Continua
        </Button>
        </form>
        );
    }
}

export default FormUtenteAnagrafica;

Body:
useState is a React hook which planned for functional components and you are creating Class components, So you can determine your state somewhere like constructor method. e.g:

class MyComponent extends React.Component {
   constructor() {
     super();

     this.state = {
       myVar1: myValue,
       myVar2: {id:1, title:'foo'}
     }
   }
   // ...
}

Then you can change your variables using setState method which inherits from Component class like this:

  <Button onClick={()=>this.setState({myVar: 'myValue'})} />

Please study first.


问:
javascript - get domain ONLY from document.referrer
I would like to get ONLY the domain from the referrer urls. The referrer urls I mostly get are http://www.davidj.com/pages/flyer.asp & http://www.ronniej.com/linkdes.com/?adv=267&loc=897

Whenver I get referrer urls like the above, I just want to get the domain example: http://www.davidj.com

I have tried using the .split method but i am having trouble using it.

答:
The only answer to get protocol + domain from referrer string is:

```
document.referrer.split("/").slice(0,3).join("/").split("?").slice(0,1).join("?")
```

The second split is needed to remove query-string if exists: http://www.example.com?s=search

it will work for:

http://....

https://....

http://www.example.com

http://www.example.com/

http://www.example.com/aaa/bbb/ccc....

http://www.example.com?s=search&t=time

http://www.example.com/?s=search&t=time

Body:
The only answer to get protocol + domain from referrer string is:

document.referrer.split("/").slice(0,3).join("/").split("?").slice(0,1).join("?")

The second split is needed to remove query-string if exists: http://www.example.com?s=search

it will work for:

http://....

https://....

http://www.example.com

http://www.example.com/

http://www.example.com/aaa/bbb/ccc....

http://www.example.com?s=search&t=time

http://www.example.com/?s=search&t=time


问:
How to remove all definitions from a loaded swf?
I use Loader.unloadAndStop() function on loader which was used to load an SWF, but I can still reach classes using getDefinitionByName. How to remove them from the memory?

答:
There is no easy way to do this. In actionscript 3 objects and classes stay in memory until they are cleaned up by the garbage collector. But the Garbage collector only runs when it wants. So you cannot know when or if it has run.
Also - if there are references to the objects in memory - such as event listeners - that refer to the classes, and those listeners are not removed, the object will persist indefinitely.
This is a pretty good article on Garbage Collection in AS3
http://www.adobe.com/devnet/flashplayer/articles/garbage_collection.html

If you can make it through, you'll have a good idea how to deal with your problem, and when not to worry as well.


问:
Android how to Get the Calls counts for specific date
I am trying to get the calls count for missed/incoming/outgoing calls for a specific date

Got the below code working fine but its getting all the calls count overall (for every date)

```<code>String[] projectionMissed = { CallLog.Calls.CACHED_NAME, CallLog.Calls.CACHED_NUMBER_LABEL, CallLog.Calls.TYPE };
        String whereMissed = CallLog.Calls.TYPE+"="+CallLog.Calls.MISSED_TYPE;
        Cursor m = getContentResolver().query(CallLog.Calls.CONTENT_URI, projectionMissed,whereMissed, null, null);
        m.moveToFirst();

        String[] projectionIncoming = { CallLog.Calls.CACHED_NAME, CallLog.Calls.CACHED_NUMBER_LABEL, CallLog.Calls.TYPE };
        String whereIncoming = CallLog.Calls.TYPE+"="+CallLog.Calls.INCOMING_TYPE;
        Cursor i = getContentResolver().query(CallLog.Calls.CONTENT_URI, projectionIncoming,whereIncoming, null, null);
        i.moveToFirst();

        String[] projectionOutgoing = { CallLog.Calls.CACHED_NAME, CallLog.Calls.CACHED_NUMBER_LABEL, CallLog.Calls.TYPE };
        String whereOutgoing = CallLog.Calls.TYPE+"="+CallLog.Calls.OUTGOING_TYPE;
        Cursor o = getContentResolver().query(CallLog.Calls.CONTENT_URI, projectionOutgoing,whereOutgoing, null, null);
        o.moveToFirst();

        String numberOfIn = String.valueOf(i.getCount());
        String numberOfOut = String.valueOf(o.getCount());
        String numberOfMiss = String.valueOf(m.getCount());

        inCalls.setText(numberOfIn);
        outCalls.setText(numberOfOut);
        missCalls.setText(numberOfMiss);
</code>```

I cant wrap my head on how to get the count of calls for example todays date can anyone provide me with atleast hints on where shall i look or what i am missing

i tried this solution but it returns the calls as 0 which is not

```<code>String[] projectionMissed = { CallLog.Calls.CACHED_NAME, CallLog.Calls.CACHED_NUMBER_LABEL, CallLog.Calls.TYPE };
        String whereMissed = CallLog.Calls.TYPE+"="+CallLog.Calls.MISSED_TYPE+ " AND " + CallLog.Calls.DATE + "=" + datetoday.getDate();
        Cursor m = getContentResolver().query(CallLog.Calls.CONTENT_URI, projectionMissed,whereMissed, null, null);
        m.moveToFirst();
</code>```

答:
After looking into the answer provided by @forthelulx and getting to know that the CallLog.Calls.DATE is returning the date in milliseconds.

got it working exactly as intended and returning the number of the type of calls for the day

Here is the code if anyone requires it

```<code>    Date c = Calendar.getInstance().getTime();
    System.out.println("Current time => " + c);

    SimpleDateFormat df = new SimpleDateFormat("dd-MM-yy");
    final String formattedDate = df.format(c);

    long timeInMilliseconds = c.getTime();
    long timeInMiliDayBefore = timeInMilliseconds - 86400000;

    String[] projectionMissed = { CallLog.Calls.CACHED_NAME, CallLog.Calls.CACHED_NUMBER_LABEL, CallLog.Calls.TYPE };
    String whereMissed = CallLog.Calls.TYPE+"="+CallLog.Calls.MISSED_TYPE+ " AND " + CallLog.Calls.DATE + ">=" + timeInMiliDayBefore;
    Cursor m = getContentResolver().query(CallLog.Calls.CONTENT_URI, projectionMissed,whereMissed, null, null);
    m.moveToFirst();

    String[] projectionIncoming = { CallLog.Calls.CACHED_NAME, CallLog.Calls.CACHED_NUMBER_LABEL, CallLog.Calls.TYPE };
    String whereIncoming = CallLog.Calls.TYPE+"="+CallLog.Calls.INCOMING_TYPE+ " AND " + CallLog.Calls.DATE + ">=" + timeInMiliDayBefore;
    Cursor i = getContentResolver().query(CallLog.Calls.CONTENT_URI, projectionIncoming,whereIncoming , null, null);
    i.moveToFirst();

    String[] projectionOutgoing = { CallLog.Calls.CACHED_NAME, CallLog.Calls.CACHED_NUMBER_LABEL, CallLog.Calls.TYPE };
    String whereOutgoing = CallLog.Calls.TYPE+"="+CallLog.Calls.OUTGOING_TYPE+ " AND " + CallLog.Calls.DATE + ">=" + timeInMiliDayBefore;
    Cursor o = getContentResolver().query(CallLog.Calls.CONTENT_URI, projectionOutgoing,whereOutgoing , null, null);
    o.moveToFirst();

    String numberOfIn = String.valueOf(i.getCount());
    String numberOfOut = String.valueOf(o.getCount());
    String numberOfMiss = String.valueOf(m.getCount());

    inCalls.setText(numberOfIn);
    outCalls.setText(numberOfOut);
    missCalls.setText(numberOfMiss);
</code>```

Body:
I am trying to get the calls count for missed/incoming/outgoing calls for a specific date

Got the below code working fine but its getting all the calls count overall (for every date)

String[] projectionMissed = { CallLog.Calls.CACHED_NAME, CallLog.Calls.CACHED_NUMBER_LABEL, CallLog.Calls.TYPE };
        String whereMissed = CallLog.Calls.TYPE+"="+CallLog.Calls.MISSED_TYPE;
        Cursor m = getContentResolver().query(CallLog.Calls.CONTENT_URI, projectionMissed,whereMissed, null, null);
        m.moveToFirst();

        String[] projectionIncoming = { CallLog.Calls.CACHED_NAME, CallLog.Calls.CACHED_NUMBER_LABEL, CallLog.Calls.TYPE };
        String whereIncoming = CallLog.Calls.TYPE+"="+CallLog.Calls.INCOMING_TYPE;
        Cursor i = getContentResolver().query(CallLog.Calls.CONTENT_URI, projectionIncoming,whereIncoming, null, null);
        i.moveToFirst();

        String[] projectionOutgoing = { CallLog.Calls.CACHED_NAME, CallLog.Calls.CACHED_NUMBER_LABEL, CallLog.Calls.TYPE };
        String whereOutgoing = CallLog.Calls.TYPE+"="+CallLog.Calls.OUTGOING_TYPE;
        Cursor o = getContentResolver().query(CallLog.Calls.CONTENT_URI, projectionOutgoing,whereOutgoing, null, null);
        o.moveToFirst();

        String numberOfIn = String.valueOf(i.getCount());
        String numberOfOut = String.valueOf(o.getCount());
        String numberOfMiss = String.valueOf(m.getCount());

        inCalls.setText(numberOfIn);
        outCalls.setText(numberOfOut);
        missCalls.setText(numberOfMiss);

I cant wrap my head on how to get the count of calls for example todays date can anyone provide me with atleast hints on where shall i look or what i am missing

i tried this solution but it returns the calls as 0 which is not

String[] projectionMissed = { CallLog.Calls.CACHED_NAME, CallLog.Calls.CACHED_NUMBER_LABEL, CallLog.Calls.TYPE };
        String whereMissed = CallLog.Calls.TYPE+"="+CallLog.Calls.MISSED_TYPE+ " AND " + CallLog.Calls.DATE + "=" + datetoday.getDate();
        Cursor m = getContentResolver().query(CallLog.Calls.CONTENT_URI, projectionMissed,whereMissed, null, null);
        m.moveToFirst();

Body:
After looking into the answer provided by @forthelulx and getting to know that the CallLog.Calls.DATE is returning the date in milliseconds.

got it working exactly as intended and returning the number of the type of calls for the day

Here is the code if anyone requires it

    Date c = Calendar.getInstance().getTime();
    System.out.println("Current time => " + c);

    SimpleDateFormat df = new SimpleDateFormat("dd-MM-yy");
    final String formattedDate = df.format(c);

    long timeInMilliseconds = c.getTime();
    long timeInMiliDayBefore = timeInMilliseconds - 86400000;

    String[] projectionMissed = { CallLog.Calls.CACHED_NAME, CallLog.Calls.CACHED_NUMBER_LABEL, CallLog.Calls.TYPE };
    String whereMissed = CallLog.Calls.TYPE+"="+CallLog.Calls.MISSED_TYPE+ " AND " + CallLog.Calls.DATE + ">=" + timeInMiliDayBefore;
    Cursor m = getContentResolver().query(CallLog.Calls.CONTENT_URI, projectionMissed,whereMissed, null, null);
    m.moveToFirst();

    String[] projectionIncoming = { CallLog.Calls.CACHED_NAME, CallLog.Calls.CACHED_NUMBER_LABEL, CallLog.Calls.TYPE };
    String whereIncoming = CallLog.Calls.TYPE+"="+CallLog.Calls.INCOMING_TYPE+ " AND " + CallLog.Calls.DATE + ">=" + timeInMiliDayBefore;
    Cursor i = getContentResolver().query(CallLog.Calls.CONTENT_URI, projectionIncoming,whereIncoming , null, null);
    i.moveToFirst();

    String[] projectionOutgoing = { CallLog.Calls.CACHED_NAME, CallLog.Calls.CACHED_NUMBER_LABEL, CallLog.Calls.TYPE };
    String whereOutgoing = CallLog.Calls.TYPE+"="+CallLog.Calls.OUTGOING_TYPE+ " AND " + CallLog.Calls.DATE + ">=" + timeInMiliDayBefore;
    Cursor o = getContentResolver().query(CallLog.Calls.CONTENT_URI, projectionOutgoing,whereOutgoing , null, null);
    o.moveToFirst();

    String numberOfIn = String.valueOf(i.getCount());
    String numberOfOut = String.valueOf(o.getCount());
    String numberOfMiss = String.valueOf(m.getCount());

    inCalls.setText(numberOfIn);
    outCalls.setText(numberOfOut);
    missCalls.setText(numberOfMiss);


问:
julia implement convert for struct containing NTuple
I'm trying to implement a convert for struct containing NTuple:

```<code>import Base: convert

abstract type AbstractMyType{N, T} end

struct MyType1{N, T} <: AbstractMyType{N, T}
    data::NTuple{T, N}
end

struct MyType2{N, T} <: AbstractMyType{N, T}
    data::NTuple{T, N}
end

foo(::Type{MyType2}, x::AbstractMyType{N, T}) where {N, T} = x
convert(::Type{MyType2}, x::AbstractMyType{N, T}) where {N, T} = MyType2{T}(x.data)

println(foo(MyType2, MyType1((1,2,3))))         # MyType1{Int64,3}((1, 2, 3))
println(convert(MyType2, MyType1((1,2,3))))     # MethodError
</code>```

Defined functions foo and convert have the same signature. For some reason function foo returns normally while convert throws MethodError. Why Julia cannot find my convert method?

julia version 1.4.1

答:
Julia is finding your convert method:

```<code>julia> println(convert(MyType2, MyType1((1,2,3))))     # MethodError
ERROR: MethodError: no method matching MyType2{3,T} where T(::Tuple{Int64,Int64,Int64})
Stacktrace:
 [1] convert(::Type{MyType2}, ::MyType1{Int64,3}) at ./REPL[16]:1
 [2] top-level scope at REPL[18]:1
</code>```

That stack trace is saying that it's inside your convert function (in my case, I defined it on the first line of the 16th REPL prompt).  The problem is that it cannot find a MyType2{T}(::Tuple) constructor.

Julia automatically creates a number of constructors for you when you don't use an inner constructor; in this case you can either call MyType(()) or MyType{T, N}(()), but Julia doesn't know what to do with only one type parameter passed (by default):

```<code>julia> MyType2((1,2,3))
MyType2{Int64,3}((1, 2, 3))

julia> MyType2{Int, 3}((1,2,3))
MyType2{Int64,3}((1, 2, 3))

julia> MyType2{Int}((1,2,3))
ERROR: MethodError: no method matching MyType2{Int64,T} where T(::Tuple{Int64,Int64,Int64})
Stacktrace:
 [1] top-level scope at REPL[7]:1
 [2] eval(::Module, ::Any) at ./boot.jl:331
 [3] eval_user_input(::Any, ::REPL.REPLBackend) at /Users/mbauman/Julia/release-1.4/usr/share/julia/stdlib/v1.4/REPL/src/REPL.jl:86
 [4] run_backend(::REPL.REPLBackend) at /Users/mbauman/.julia/packages/Revise/AMRie/src/Revise.jl:1023
 [5] top-level scope at none:0
</code>```

So the fix is either to define that method yourself, or change the body of your convert method to call MyType{T,N} explicitly.

Body:
I'm trying to implement a convert for struct containing NTuple:

import Base: convert

abstract type AbstractMyType{N, T} end

struct MyType1{N, T} <: AbstractMyType{N, T}
    data::NTuple{T, N}
end

struct MyType2{N, T} <: AbstractMyType{N, T}
    data::NTuple{T, N}
end

foo(::Type{MyType2}, x::AbstractMyType{N, T}) where {N, T} = x
convert(::Type{MyType2}, x::AbstractMyType{N, T}) where {N, T} = MyType2{T}(x.data)

println(foo(MyType2, MyType1((1,2,3))))         # MyType1{Int64,3}((1, 2, 3))
println(convert(MyType2, MyType1((1,2,3))))     # MethodError

Defined functions foo and convert have the same signature. For some reason function foo returns normally while convert throws MethodError. Why Julia cannot find my convert method?

julia version 1.4.1

Body:
Julia is finding your convert method:

julia> println(convert(MyType2, MyType1((1,2,3))))     # MethodError
ERROR: MethodError: no method matching MyType2{3,T} where T(::Tuple{Int64,Int64,Int64})
Stacktrace:
 [1] convert(::Type{MyType2}, ::MyType1{Int64,3}) at ./REPL[16]:1
 [2] top-level scope at REPL[18]:1

That stack trace is saying that it's inside your convert function (in my case, I defined it on the first line of the 16th REPL prompt).  The problem is that it cannot find a MyType2{T}(::Tuple) constructor.

Julia automatically creates a number of constructors for you when you don't use an inner constructor; in this case you can either call MyType(()) or MyType{T, N}(()), but Julia doesn't know what to do with only one type parameter passed (by default):

julia> MyType2((1,2,3))
MyType2{Int64,3}((1, 2, 3))

julia> MyType2{Int, 3}((1,2,3))
MyType2{Int64,3}((1, 2, 3))

julia> MyType2{Int}((1,2,3))
ERROR: MethodError: no method matching MyType2{Int64,T} where T(::Tuple{Int64,Int64,Int64})
Stacktrace:
 [1] top-level scope at REPL[7]:1
 [2] eval(::Module, ::Any) at ./boot.jl:331
 [3] eval_user_input(::Any, ::REPL.REPLBackend) at /Users/mbauman/Julia/release-1.4/usr/share/julia/stdlib/v1.4/REPL/src/REPL.jl:86
 [4] run_backend(::REPL.REPLBackend) at /Users/mbauman/.julia/packages/Revise/AMRie/src/Revise.jl:1023
 [5] top-level scope at none:0

So the fix is either to define that method yourself, or change the body of your convert method to call MyType{T,N} explicitly.


问:
How to fit a piecewise regression in R, and constrain the first fit to pass through the intercept..?
I would like to perform a broken-stick regression in which the intercept of the first segment is constrained to pass through the origin.

The below code uses the 'segmented' package in R to fit two linear models to the data.

Notice though that the regression for the first segment does not pass through the origin - as far as I can tell, segmented does not allow the user to specify  that the intercept for the first segment should pass through the origin.

So, how would one perform such a broken-line regression, whilst constraining the first segment to pass through the origin..?

```<code>## create data with two 'growth' regimes
n <- 100
x <- 1:n
y1 <- x[1:(n/2)] + rnorm(n=n/2, mean = 0, sd=10)
y2 <-              rnorm(n=n/2, mean = 0, sd=5) + max(y1)
y <- c(y1,y2)
DF <- data.frame(x,y )

## fit a broken-stick regression model
library(segmented)
LM <- lm(y~x, DF)
Seggie <- segmented(LM, seg.Z=~x, npsi=1, psi=n/2)

## plot the data & the model
plot(Seggie); abline(h=0, lty=2); abline(v=0, lty=2)
points(y ~ x, DF); abline(h=0, lty=2)
</code>```

答:
Very nice example.

You just need to adjust your formula so that it requires going through the origin.  You can do that by adding +0 to your dependent variables. (See ?formula)

```<code>LM <- lm(y~x+0, DF)
Seggie <- segmented(LM, seg.Z=~x+0, npsi=1, psi=n/2)
plot(Seggie)
abline(h=0, lty=2); abline(v=0, lty=2)
points(y ~ x, DF); abline(h=0, lty=2)
</code>```

Body:
I would like to perform a broken-stick regression in which the intercept of the first segment is constrained to pass through the origin.

The below code uses the 'segmented' package in R to fit two linear models to the data.

Notice though that the regression for the first segment does not pass through the origin - as far as I can tell, segmented does not allow the user to specify  that the intercept for the first segment should pass through the origin.

So, how would one perform such a broken-line regression, whilst constraining the first segment to pass through the origin..?

## create data with two 'growth' regimes
n <- 100
x <- 1:n
y1 <- x[1:(n/2)] + rnorm(n=n/2, mean = 0, sd=10)
y2 <-              rnorm(n=n/2, mean = 0, sd=5) + max(y1)
y <- c(y1,y2)
DF <- data.frame(x,y )

## fit a broken-stick regression model
library(segmented)
LM <- lm(y~x, DF)
Seggie <- segmented(LM, seg.Z=~x, npsi=1, psi=n/2)

## plot the data & the model
plot(Seggie); abline(h=0, lty=2); abline(v=0, lty=2)
points(y ~ x, DF); abline(h=0, lty=2)

Body:
Very nice example.

You just need to adjust your formula so that it requires going through the origin.  You can do that by adding +0 to your dependent variables. (See ?formula)

LM <- lm(y~x+0, DF)
Seggie <- segmented(LM, seg.Z=~x+0, npsi=1, psi=n/2)
plot(Seggie)
abline(h=0, lty=2); abline(v=0, lty=2)
points(y ~ x, DF); abline(h=0, lty=2)