答:
The geometry library for Google Maps' JavaScript API provides a useful method called google.maps.geometry.spherical.computeHeading(p1, p2) that exactly computes the heading from point1 to point2.

I took the liberty to modify your code a bit. Here's a jsfiddle.

Be careful to correctly anchor you icon, the anchor was at (0, 0) which made the car move outside of the roads. I tried to change it so that it looks more natural.

<!Doctype html>
<meta charset="UTF-8">

```

I think some parts of the code could use other methods from the API, for instance the computation of deltaLat and deltaLng, but I'm not sure.

I'm also not certain that the moveMarker() method has to be split in two conditional cases, but I may be wrong.

Title: Rotating google maps icon using bearing angle

Body:
I have this map https://jsfiddle.net/e80zkacn/ with an icon of car. At 0 degrees the icon of the car faces north but faces to where its headed when i rotate it at 270 degrees. I want the car to always face the correct position using the bearing angle.

The formula i am using is atan2 as described here https://www.igismap.com/formula-to-find-bearing-or-heading-angle-between-two-points-latitude-longitude/

This is the code

    var map, marker;
var startPos = [42.42679066670903, -83.29210638999939];
var speed = 50; // km/h
var bearing = 2.6;

var symbol = {
    path: "M62.1,36.5c-0.9-1.2-3.6-1.5-3.6-1.5c0.1-3.5,0.5-6.9,0.7-8.2c1.9-7.3-1.7-11.8-1.7-11.8c-4.8-4.8-9.1-5-12.5-5   c-3.4,0-7.8,0.3-12.5,5c0,0-3.6,4.5-1.7,11.8c0.2,1.2,0.5,4.6,0.7,8.2c0,0-2.7,0.3-3.6,1.5c-0.9,1.2-0.9,1.9,0,1.9   c0.9,0,2.9-2.3,3.6-2.3V35c0,1,0.1,2,0.1,3c0,4.4,0,33.7,0,33.7s-0.3,6.1,5,7.8c1.2,0,4.6,0.4,8.4,0.5c3.8-0.1,7.3-0.5,8.4-0.5   c5.3-1.7,5-7.8,5-7.8s0-29.3,0-33.7c0-1,0-2,0.1-3v1.2c0.7,0,2.7,2.3,3.6,2.3C63,38.5,63,37.7,62.1,36.5z M34.7,66.5   c-0.3,3.3-2.3,4.1-2.3,4.1V37.4c0.8,1.2,2.3,6.8,2.3,6.8S34.9,63.2,34.7,66.5z M54.8,75.2c0,0-4.2,2.3-9.8,2.2   c-5.6,0.1-9.8-2.2-9.8-2.2v-2.8c4.9,2.2,9.8,2.2,9.8,2.2s4.9,0,9.8-2.2V75.2z M35.2,41.1l-1.7-10.2c0,0,4.5-3.2,11.5-3.2   s11.5,3.2,11.5,3.2l-1.7,10.2C51.4,39.2,38.6,39.2,35.2,41.1z M57.7,70.6c0,0-2.1-0.8-2.3-4.1c-0.3-3.3,0-22.4,0-22.4   s1.5-5.6,2.3-6.8V70.6z",
    fillColor: '#FF0000',
    fillOpacity: .5,
    anchor: new google.maps.Point(0, 0),
    strokeWeight: 1,
    scale: .5,
    rotation: bearing
}

var delay = 100;
// If you set the delay below 1000ms and you go to another tab,
// the setTimeout function will wait to be the active tab again
// before running the code.
// See documentation :
// https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout#Inactive_tabs

function animateMarker(marker, coords, km_h)
{
    var target = 0;
    var km_h = km_h || 50;
    coords.push([startPos[0], startPos[1]]);

    function goToPoint()
    {

    function radians_to_degrees(radians)
{
  var pi = Math.PI;
  return radians * (180/pi);
}

        var lat = marker.position.lat();
        var lng = marker.position.lng();
        var step = (km_h * 1000 * delay) / 3600000; // in meters

        var dest = new google.maps.LatLng(
        coords[target][0], coords[target][1]);

        var distance =
        google.maps.geometry.spherical.computeDistanceBetween(
        dest, marker.position); // in meters

        var numStep = distance / step;
        var i = 0;
        var deltaLat = (coords[target][0] - lat) / numStep;
        var deltaLng = (coords[target][1] - lng) / numStep;

        function the_bearing(){
        //console.log('x', lat);
        //console.log('y', lng);
        let bear = Math.atan2(lat, lng);

       var brng = radians_to_degrees(bear);
       brng = (brng + 360) % 360;

        console.log('angle is ', brng);
        }
        the_bearing();

        function moveMarker()
        {
            lat += deltaLat;
            lng += deltaLng;
            i += step;

            if (i < distance)
            {
                marker.setPosition(new google.maps.LatLng(lat, lng));
                setTimeout(moveMarker, delay);
            }
            else
            {   marker.setPosition(dest);
                target++;
                if (target == coords.length){ target = 0; }

                setTimeout(goToPoint, delay);
            }
        }
        moveMarker();

    }
    goToPoint();
}

function initialize()
{
    var myOptions = {
        zoom: 16,
        center: new google.maps.LatLng(42.425175091823974, -83.2943058013916),
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    map = new google.maps.Map(document.getElementById("map"), myOptions);
    var icon = symbol;

    marker = new google.maps.Marker({
        position: new google.maps.LatLng(startPos[0], startPos[1]),
        map: map,
        icon: icon
    });

    google.maps.event.addListenerOnce(map, 'idle', function()
    {
        animateMarker(marker, [
            // The coordinates of each point you want the marker to go to.
            // You don't need to specify the starting position again.
            [42.42666395645802, -83.29694509506226],
            [42.42300508749226, -83.29679489135742],
            [42.42304468678425, -83.29434871673584],
            [42.424882066428424, -83.2944130897522],
            [42.42495334300206, -83.29203128814697]
        ], speed);
    });
}

initialize();

Currently the results of atan2 are being converted to degrees and i am doubting my method. How can i make the svg icon to always face where its going and is there a reliable method i can use to always make the car icon look towards the direction its heading?.

Body:
The geometry library for Google Maps' JavaScript API provides a useful method called google.maps.geometry.spherical.computeHeading(p1, p2) that exactly computes the heading from point1 to point2.

I took the liberty to modify your code a bit. Here's a jsfiddle.

Be careful to correctly anchor you icon, the anchor was at (0, 0) which made the car move outside of the roads. I tried to change it so that it looks more natural.

<!Doctype html>
<meta charset="UTF-8">
<head>
<style>
#map {
    width: 600px;
    height: 400px;
}
</style>

</head>
<body>
<div id="map"></div>
<script src="https://code.jquery.com/jquery-3.4.1.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBx6MYRybsImp6aSn4xPphPFlGF3IaOr88&libraries=geometry"></script>
<script type="text/javascript">
var map, marker;
var startPos = [42.42679066670903, -83.29210638999939];
var speed = 270; // km/h
var bearing = 270;

var symbol = {
    path: "M62.1,36.5c-0.9-1.2-3.6-1.5-3.6-1.5c0.1-3.5,0.5-6.9,0.7-8.2c1.9-7.3-1.7-11.8-1.7-11.8c-4.8-4.8-9.1-5-12.5-5   c-3.4,0-7.8,0.3-12.5,5c0,0-3.6,4.5-1.7,11.8c0.2,1.2,0.5,4.6,0.7,8.2c0,0-2.7,0.3-3.6,1.5c-0.9,1.2-0.9,1.9,0,1.9   c0.9,0,2.9-2.3,3.6-2.3V35c0,1,0.1,2,0.1,3c0,4.4,0,33.7,0,33.7s-0.3,6.1,5,7.8c1.2,0,4.6,0.4,8.4,0.5c3.8-0.1,7.3-0.5,8.4-0.5   c5.3-1.7,5-7.8,5-7.8s0-29.3,0-33.7c0-1,0-2,0.1-3v1.2c0.7,0,2.7,2.3,3.6,2.3C63,38.5,63,37.7,62.1,36.5z M34.7,66.5   c-0.3,3.3-2.3,4.1-2.3,4.1V37.4c0.8,1.2,2.3,6.8,2.3,6.8S34.9,63.2,34.7,66.5z M54.8,75.2c0,0-4.2,2.3-9.8,2.2   c-5.6,0.1-9.8-2.2-9.8-2.2v-2.8c4.9,2.2,9.8,2.2,9.8,2.2s4.9,0,9.8-2.2V75.2z M35.2,41.1l-1.7-10.2c0,0,4.5-3.2,11.5-3.2   s11.5,3.2,11.5,3.2l-1.7,10.2C51.4,39.2,38.6,39.2,35.2,41.1z M57.7,70.6c0,0-2.1-0.8-2.3-4.1c-0.3-3.3,0-22.4,0-22.4   s1.5-5.6,2.3-6.8V70.6z",
    fillColor: '#FF0000',
    fillOpacity: .5,
    anchor: new google.maps.Point(45, 45),
    strokeWeight: 1,
    scale: .5,
    rotation: bearing
}

var delay = 100;
// If you set the delay below 1000ms and you go to another tab,
// the setTimeout function will wait to be the active tab again
// before running the code.
// See documentation :
// https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout#Inactive_tabs

function animateMarker(marker, coords, km_h)
{
    var target = 0;
    var km_h = km_h || 50;
    coords.push([startPos[0], startPos[1]]);
    console.log(coords);

    function goToPoint()
    {
        var lastPosn = marker.getPosition();
        var lat = marker.position.lat();
        var lng = marker.position.lng();
        var step = (km_h * 1000 * delay) / 3600000; // in meters

        var start = new google.maps.LatLng(startPos[0], startPos[1]);
        var dest = new google.maps.LatLng(coords[target][0], coords[target][1]);

        var distance = google.maps.geometry.spherical.computeDistanceBetween(dest, marker.position); // in meters

        var numStep = distance / step;
        var i = 0;
        var deltaLat = (coords[target][0] - lat) / numStep;
        var deltaLng = (coords[target][1] - lng) / numStep;

        function moveMarker()
        {
            lat += deltaLat;
            lng += deltaLng;
            i += step;

            if (i < distance)
            {
                var p = new google.maps.LatLng(lat, lng);
                marker.setPosition(p);

                var heading = google.maps.geometry.spherical.computeHeading(lastPosn, p);
                symbol.rotation = heading;
                marker.setIcon(symbol);

                setTimeout(moveMarker, delay);
            }
            else
            {
                marker.setPosition(dest);

                var heading = google.maps.geometry.spherical.computeHeading(lastPosn, dest);
                symbol.rotation = heading;
                marker.setIcon(symbol);

                target++;
                if (target == coords.length){ target = 0; }

                setTimeout(goToPoint, delay);
            }
        }

        moveMarker();
    }
    goToPoint();
}

function initialize()
{
    var myOptions = {
        zoom: 16,
        center: new google.maps.LatLng(42.425175091823974, -83.2943058013916),
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    map = new google.maps.Map(document.getElementById("map"), myOptions);

    marker = new google.maps.Marker({
        position: new google.maps.LatLng(startPos[0], startPos[1]),
        map: map,
        icon: symbol
    });

    google.maps.event.addListenerOnce(map, 'idle', function()
    {
        animateMarker(marker, [
            // The coordinates of each point you want the marker to go to.
            // You don't need to specify the starting position again.
            [42.42666395645802, -83.29694509506226],
            [42.42300508749226, -83.29679489135742],
            [42.42304468678425, -83.29434871673584],
            [42.424882066428424, -83.2944130897522],
            [42.42495334300206, -83.29203128814697]
        ], speed);
    });
}

initialize();
</script>
</body>
</html>

I think some parts of the code could use other methods from the API, for instance the computation of deltaLat and deltaLng, but I'm not sure.

I'm also not certain that the moveMarker() method has to be split in two conditional cases, but I may be wrong.


来源: stackexchange

问:
Python Speedtest facing problems with certification _ssl.c:1056
I am trying to use the following code, on Speedtest API

```<code>    def get_bytes(self):
        s = speedtest.Speedtest()
        s.get_best_server()
        s.download()
        s.upload()
        res = s.results.dict()
        print(res["download"], res["upload"], res["ping"])
</code>```

However I am facing some problems with this connection. All the times I am receiving this error.

```<code>speedtest.ConfigRetrievalError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1056)>
</code>```

I am using Python 3.7 on a MacOS Mojave and already tried to update the certifi on virtualenv

Do you have any idea?

答:
I guys, finally I found the error.
In this case, you need to install the certifications on your machines.

The certification are:
MacintoshHD > Applications > Python 3.7 > Install Certificates.command

Double click on certifications and its going to work this solution.

ContentLicense: CC BY-SA 4.0

Body:
I am trying to use the following code, on Speedtest API

    def get_bytes(self):
        s = speedtest.Speedtest()
        s.get_best_server()
        s.download()
        s.upload()
        res = s.results.dict()
        print(res["download"], res["upload"], res["ping"])

However I am facing some problems with this connection. All the times I am receiving this error.

speedtest.ConfigRetrievalError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1056)>

I am using Python 3.7 on a MacOS Mojave and already tried to update the certifi on virtualenv

Do you have any idea?


问:
How to convert rxJava2's Observable to Completable?
I have Observable stream, and I want to convert it to Completable, how I could do that?</p>

答:
As I understand all this solutions will work only if Observable call onComplete, which is not enough if you want your result Completable to trigger after first onNext or onError, so for this case I'd recommend this:

```<code>Observable<Integer> observable = Observable.just(1, 2, 3);
Completable completable = observable.firstOrError().ignoreElement()
</code>```

ContentLicense: CC BY-SA 3.0

Body:
As I understand all this solutions will work only if Observable call onComplete, which is not enough if you want your result Completable to trigger after first onNext or onError, so for this case I'd recommend this:

Observable<Integer> observable = Observable.just(1, 2, 3);
Completable completable = observable.firstOrError().ignoreElement()


问:
How to track a spoke of a wheel in two subsequent video frames?
Consider two subsequent frames of a video that look as follows:

What is a possible way to track the movement of one of the spokes?

I am asking this because I don't have any experience with video processing. So any advice would be helpful! What am I tracking? From what I have read, usually I would have to detect the object I want to track first. And I am using a corner detection algorithm for this such as goodfeaturestotrack. But how do I make sure I detect the correct spoke, etc. ?

Some additional information: The framerate of the video is 30fps. The wheel rotates in clockwise-direction only. And when I click through the video frame by frame it is pretty obvious that a spoke does not move by more than half of the angle between two spokes (from frame to frame).
Also: The radius of the wheel is 5cm.

I have now tried out Mark's answer. I have logged Tmax and the timestamp of the frame in a txt-file and then wrote the following code to compute the corresponding velocity:

```<code>ListOfVelocities = []
for idx in range(1,len(ListOfAngles)):
    if ListOfAngles[idx] < ListOfAngles[idx-1]:
        rotation = (360-ListOfAngles[idx]) + ListOfAngles[idx-1]
    else:
        rotation = ListOfAngles[idx] - ListOfAngles[idx-1]
    timePassed = VideoTimestamp[idx]-VideoTimestamp[idx-1]
    velocity = 2*np.pi/360 * rotation * RADIUS * timePassed
    ListOfVelocities.append(velocity)
</code>```

答:
I don't really perceive this as a tracking problem because the wheel is constrained so it can't move about all over the frame, it can only change its angular position, so you only really need to know where some part of it is in one frame and how much it has rotated by in the next frame. Then, as you know the framerate, i.e. the time between frames, you can calculate the speed.

So, the question is how to tell which is the same spoke that you measured in the previous frame. As the area behind the spokes is dark, you would want a light spoke to contrast well so you can find it easily. So, I would paint four of the spokes black, then you are just looking for one light one on a dark background. I would also consider painting the centre of the wheel red (or other saturated colour), so you can easily find the middle.

Now, at the start of processing, find the centre of the wheel by looking for red and get its x,y coordinates in the image. Now choose a radius in pixels that you can alter later, and work out a list of the x,y coordinates of say 360 points (1 per degree) on the circumference of the circle centred on and going around the red point. These points and all the sines/cosines will not change all through your processing, so do this outside your main video processing loop.

Now at each frame, use indexing to pick up the brightness at each of the 360 points and, initially at least, take the brightest one as the spoke.

So, I have crudely painted on your image so the centre is red and just one spoke is white:

Now the code looks something like this:

```<code>#!/usr/bin/env python3

import math
import numpy as np
from PIL import Image

# Open image and make Numpy version of it too
im = Image.open('wheel.png')
imnp = np.array(im)

# Find centre by looking for red pixels
# See https://stackoverflow.com/a/52183666/2836621
x, y = 193, 168

# Set up list of 360 points on a circle centred on red dot outside main processing loop
radius = 60
# List of X values and Y values on circumference
Xs = []
Ys = []
for theta in range(360):
    thetaRad = math.radians(theta)
    dx = int(radius * math.sin(thetaRad))
    dy = int(radius * math.cos(thetaRad))
    Xs.append(x+dx)
    Ys.append(y+dy)

# Your main loop processing frames starts here

# Make greyscale Numpy version of image
grey = np.array(im.convert('L'))

sum  = 0
Bmax = 0
Tmax = 0
for theta in range(360):
    brightness=grey[Ys[theta],Xs[theta]]
    sum += brightness
    if brightness > Bmax:
        Bmax = brightness
        Tmax = theta
    print(f"theta: {theta}: brightness={brightness}")

# Calculate mean
Mgrey = sum/len(Xs)
print(f"Mean brightness on circumf: {Mgrey}")

# Print peak brightness and matching theta
print(f"Peak brightness: {Bmax} at theta: {Tmax}")
</code>```

And the output is like this:

```<code>theta: 0: brightness=38
theta: 5: brightness=38
theta: 10: brightness=38
theta: 15: brightness=38
theta: 20: brightness=38
theta: 25: brightness=38
theta: 30: brightness=38
theta: 35: brightness=45
theta: 40: brightness=38
theta: 45: brightness=33
theta: 50: brightness=30
theta: 55: brightness=28
theta: 60: brightness=28
theta: 65: brightness=31
theta: 70: brightness=70
theta: 75: brightness=111
theta: 80: brightness=130
theta: 85: brightness=136
theta: 90: brightness=139    <--- peak brightness at 90 degrees to vertical as per picture - thankfully!
theta: 95: brightness=122
theta: 100: brightness=82
theta: 105: brightness=56
theta: 110: brightness=54
theta: 115: brightness=49
theta: 120: brightness=43
theta: 125: brightness=38
theta: 130: brightness=38
theta: 135: brightness=38
theta: 140: brightness=38
theta: 145: brightness=38
theta: 150: brightness=38
theta: 155: brightness=38
theta: 160: brightness=38
theta: 165: brightness=38
theta: 170: brightness=38
theta: 175: brightness=38
theta: 180: brightness=31
theta: 185: brightness=33
theta: 190: brightness=38
theta: 195: brightness=48
theta: 200: brightness=57
theta: 205: brightness=38
theta: 210: brightness=38
theta: 215: brightness=38
theta: 220: brightness=38
theta: 225: brightness=38
theta: 230: brightness=38
theta: 235: brightness=38
theta: 240: brightness=38
theta: 245: brightness=38
theta: 250: brightness=52
theta: 255: brightness=47
theta: 260: brightness=36
theta: 265: brightness=35
theta: 270: brightness=32
theta: 275: brightness=32
theta: 280: brightness=29
theta: 285: brightness=38
theta: 290: brightness=38
theta: 295: brightness=38
theta: 300: brightness=38
theta: 305: brightness=38
theta: 310: brightness=38
theta: 315: brightness=38
theta: 320: brightness=39
theta: 325: brightness=40
theta: 330: brightness=42
theta: 335: brightness=42
theta: 340: brightness=40
theta: 345: brightness=36
theta: 350: brightness=35
theta: 355: brightness=38
Mean brightness on circumf: 45.87222222222222
Peak brightness: 142 at theta: 89
</code>```

If, in the next frame the peak brightness is now at 100 degrees to vertical, you know the wheel has rotated 10 degrees in 1/(frames_per_second).

You may need to vary the radius for best results - experiment! The white radius shown on the image corresponds to the 60 pixels radius in the code.

Rather than taking the peak brightness, you may want to find the mean and standard deviation of the brightness of the 360 pixels on the circumference and then take the angle as the average of the angles where the brightness is more than some number of standard deviations above the mean. It depends on the resolution/accuracy you need.

You can also collect all the brightnesses around the circle indexed by theta into a single 360-element array like this:

```<code>brightnessByTheta = grey[Ys[:],Xs[:]]
</code>```

and you'll get:

```<code>array([ 38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,
        38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,
        38,  38,  38,  38,  38,  43,  49,  47,  46,  45,  44,  43,  43,
        40,  38,  36,  34,  33,  33,  33,  32,  31,  31,  29,  30,  28,
        29,  29,  29,  28,  28,  27,  29,  28,  28,  27,  28,  28,  29,
        31,  36,  42,  51,  60,  70,  81,  89,  98, 105, 111, 117, 122,
       126, 128, 130, 131, 132, 133, 135, 136, 138, 139, 141, 142, 139,
       136, 133, 129, 124, 122, 119, 113, 104,  93,  82,  72,  65,  60,
        59,  56,  56,  55,  55,  54,  54,  53,  52,  52,  50,  49,  47,
        46,  45,  44,  43,  42,  40,  39,  38,  38,  37,  38,  38,  37,
        38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,
        38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,
        38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,
        38,  38,  38,  38,  38,  38,  38,  38,  34,  31,  31,  31,  31,
        31,  31,  32,  33,  34,  35,  36,  37,  38,  42,  43,  44,  45,
        48,  49,  50,  51,  55,  57,  60,  64,  65,  38,  38,  38,  38,
        38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,
        38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,
        38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,
        38,  38,  38,  52,  56,  46,  46,  47,  47,  38,  39,  40,  40,
        36,  36,  36,  36,  36,  35,  35,  34,  34,  34,  32,  33,  33,
        33,  33,  32,  32,  31,  30,  29,  29,  28,  38,  38,  38,  38,
        38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,
        38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,
        38,  38,  38,  38,  38,  38,  40,  40,  39,  38,  39,  39,  39,
        40,  40,  41,  41,  42,  42,  42,  41,  41,  42,  42,  41,  40,
        39,  40,  40,  38,  39,  38,  37,  36,  36,  35,  34,  33,  35,
        38,  38,  38,  38,  38,  38,  38,  38,  38], dtype=uint8)
</code>```

Body:
Consider two subsequent frames of a video that look as follows:

What is a possible way to track the movement of one of the spokes?

I am asking this because I don't have any experience with video processing. So any advice would be helpful! What am I tracking? From what I have read, usually I would have to detect the object I want to track first. And I am using a corner detection algorithm for this such as goodfeaturestotrack. But how do I make sure I detect the correct spoke, etc. ?

Some additional information: The framerate of the video is 30fps. The wheel rotates in clockwise-direction only. And when I click through the video frame by frame it is pretty obvious that a spoke does not move by more than half of the angle between two spokes (from frame to frame).
Also: The radius of the wheel is 5cm.

I have now tried out Mark's answer. I have logged Tmax and the timestamp of the frame in a txt-file and then wrote the following code to compute the corresponding velocity:

ListOfVelocities = []
for idx in range(1,len(ListOfAngles)):
    if ListOfAngles[idx] < ListOfAngles[idx-1]:
        rotation = (360-ListOfAngles[idx]) + ListOfAngles[idx-1]
    else:
        rotation = ListOfAngles[idx] - ListOfAngles[idx-1]
    timePassed = VideoTimestamp[idx]-VideoTimestamp[idx-1]
    velocity = 2*np.pi/360 * rotation * RADIUS * timePassed
    ListOfVelocities.append(velocity)

Body:
I don't really perceive this as a tracking problem because the wheel is constrained so it can't move about all over the frame, it can only change its angular position, so you only really need to know where some part of it is in one frame and how much it has rotated by in the next frame. Then, as you know the framerate, i.e. the time between frames, you can calculate the speed.

So, the question is how to tell which is the same spoke that you measured in the previous frame. As the area behind the spokes is dark, you would want a light spoke to contrast well so you can find it easily. So, I would paint four of the spokes black, then you are just looking for one light one on a dark background. I would also consider painting the centre of the wheel red (or other saturated colour), so you can easily find the middle.

Now, at the start of processing, find the centre of the wheel by looking for red and get its x,y coordinates in the image. Now choose a radius in pixels that you can alter later, and work out a list of the x,y coordinates of say 360 points (1 per degree) on the circumference of the circle centred on and going around the red point. These points and all the sines/cosines will not change all through your processing, so do this outside your main video processing loop.

Now at each frame, use indexing to pick up the brightness at each of the 360 points and, initially at least, take the brightest one as the spoke.

So, I have crudely painted on your image so the centre is red and just one spoke is white:

Now the code looks something like this:

#!/usr/bin/env python3

import math
import numpy as np
from PIL import Image

# Open image and make Numpy version of it too
im = Image.open('wheel.png')
imnp = np.array(im)

# Find centre by looking for red pixels
# See https://stackoverflow.com/a/52183666/2836621
x, y = 193, 168

# Set up list of 360 points on a circle centred on red dot outside main processing loop
radius = 60
# List of X values and Y values on circumference
Xs = []
Ys = []
for theta in range(360):
    thetaRad = math.radians(theta)
    dx = int(radius * math.sin(thetaRad))
    dy = int(radius * math.cos(thetaRad))
    Xs.append(x+dx)
    Ys.append(y+dy)

# Your main loop processing frames starts here

# Make greyscale Numpy version of image
grey = np.array(im.convert('L'))

sum  = 0
Bmax = 0
Tmax = 0
for theta in range(360):
    brightness=grey[Ys[theta],Xs[theta]]
    sum += brightness
    if brightness > Bmax:
        Bmax = brightness
        Tmax = theta
    print(f"theta: {theta}: brightness={brightness}")

# Calculate mean
Mgrey = sum/len(Xs)
print(f"Mean brightness on circumf: {Mgrey}")

# Print peak brightness and matching theta
print(f"Peak brightness: {Bmax} at theta: {Tmax}")

And the output is like this:

theta: 0: brightness=38
theta: 5: brightness=38
theta: 10: brightness=38
theta: 15: brightness=38
theta: 20: brightness=38
theta: 25: brightness=38
theta: 30: brightness=38
theta: 35: brightness=45
theta: 40: brightness=38
theta: 45: brightness=33
theta: 50: brightness=30
theta: 55: brightness=28
theta: 60: brightness=28
theta: 65: brightness=31
theta: 70: brightness=70
theta: 75: brightness=111
theta: 80: brightness=130
theta: 85: brightness=136
theta: 90: brightness=139    <--- peak brightness at 90 degrees to vertical as per picture - thankfully!
theta: 95: brightness=122
theta: 100: brightness=82
theta: 105: brightness=56
theta: 110: brightness=54
theta: 115: brightness=49
theta: 120: brightness=43
theta: 125: brightness=38
theta: 130: brightness=38
theta: 135: brightness=38
theta: 140: brightness=38
theta: 145: brightness=38
theta: 150: brightness=38
theta: 155: brightness=38
theta: 160: brightness=38
theta: 165: brightness=38
theta: 170: brightness=38
theta: 175: brightness=38
theta: 180: brightness=31
theta: 185: brightness=33
theta: 190: brightness=38
theta: 195: brightness=48
theta: 200: brightness=57
theta: 205: brightness=38
theta: 210: brightness=38
theta: 215: brightness=38
theta: 220: brightness=38
theta: 225: brightness=38
theta: 230: brightness=38
theta: 235: brightness=38
theta: 240: brightness=38
theta: 245: brightness=38
theta: 250: brightness=52
theta: 255: brightness=47
theta: 260: brightness=36
theta: 265: brightness=35
theta: 270: brightness=32
theta: 275: brightness=32
theta: 280: brightness=29
theta: 285: brightness=38
theta: 290: brightness=38
theta: 295: brightness=38
theta: 300: brightness=38
theta: 305: brightness=38
theta: 310: brightness=38
theta: 315: brightness=38
theta: 320: brightness=39
theta: 325: brightness=40
theta: 330: brightness=42
theta: 335: brightness=42
theta: 340: brightness=40
theta: 345: brightness=36
theta: 350: brightness=35
theta: 355: brightness=38
Mean brightness on circumf: 45.87222222222222
Peak brightness: 142 at theta: 89

If, in the next frame the peak brightness is now at 100 degrees to vertical, you know the wheel has rotated 10 degrees in 1/(frames_per_second).

You may need to vary the radius for best results - experiment! The white radius shown on the image corresponds to the 60 pixels radius in the code.

Rather than taking the peak brightness, you may want to find the mean and standard deviation of the brightness of the 360 pixels on the circumference and then take the angle as the average of the angles where the brightness is more than some number of standard deviations above the mean. It depends on the resolution/accuracy you need.

You can also collect all the brightnesses around the circle indexed by theta into a single 360-element array like this:

brightnessByTheta = grey[Ys[:],Xs[:]]

and you'll get:

array([ 38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,
        38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,
        38,  38,  38,  38,  38,  43,  49,  47,  46,  45,  44,  43,  43,
        40,  38,  36,  34,  33,  33,  33,  32,  31,  31,  29,  30,  28,
        29,  29,  29,  28,  28,  27,  29,  28,  28,  27,  28,  28,  29,
        31,  36,  42,  51,  60,  70,  81,  89,  98, 105, 111, 117, 122,
       126, 128, 130, 131, 132, 133, 135, 136, 138, 139, 141, 142, 139,
       136, 133, 129, 124, 122, 119, 113, 104,  93,  82,  72,  65,  60,
        59,  56,  56,  55,  55,  54,  54,  53,  52,  52,  50,  49,  47,
        46,  45,  44,  43,  42,  40,  39,  38,  38,  37,  38,  38,  37,
        38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,
        38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,
        38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,
        38,  38,  38,  38,  38,  38,  38,  38,  34,  31,  31,  31,  31,
        31,  31,  32,  33,  34,  35,  36,  37,  38,  42,  43,  44,  45,
        48,  49,  50,  51,  55,  57,  60,  64,  65,  38,  38,  38,  38,
        38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,
        38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,
        38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,
        38,  38,  38,  52,  56,  46,  46,  47,  47,  38,  39,  40,  40,
        36,  36,  36,  36,  36,  35,  35,  34,  34,  34,  32,  33,  33,
        33,  33,  32,  32,  31,  30,  29,  29,  28,  38,  38,  38,  38,
        38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,
        38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,  38,
        38,  38,  38,  38,  38,  38,  40,  40,  39,  38,  39,  39,  39,
        40,  40,  41,  41,  42,  42,  42,  41,  41,  42,  42,  41,  40,
        39,  40,  40,  38,  39,  38,  37,  36,  36,  35,  34,  33,  35,
        38,  38,  38,  38,  38,  38,  38,  38,  38], dtype=uint8)


问:
Converting between windows and unix path with sed losses double slash
This command almost gives me what I want :-

```<code>echo "\\123.123.123.123\path1\1 - path2\path3 path4\path5" | sed 's_\\_/_g' | sed 's_ _\\ _g'
/123.123.123.123/path1/1\ -\ path2/path3\ path4/path5
</code>```

But as one can see, its lost the '//' at the beginning!

ie, desired outout :-

```<code>//123.123.123.123/path1/1\ -\ path2/path3\ path4/path5
</code>```

What am I missing?

Edit: After not testing the basics of echo (many thanks to all who pointed that out). I should of also been more clear on the end-game of this question.

I want to use this in a script, and define the windows path at the top.

How can I echo the path to a tmp file for sed?

This obviously wont work :-

```<code>WIN_PATH="\\123.123.123.123\path1\1 - path2\path3 path4\path5"
UNIX_PATH=`echo $WIN_PATH | sed 's_\\_/_g' | sed 's_ _\\ _g'`
</code>```

答:
Use single quotes instead of double quotes in echo - as it is the shell interprets your two backslashes as an escape sequence for \:

```<code>$ echo '\\123.123.123.123\path1\1 - path2\path3 path4\path5' | sed 's_\\_/_g' | sed 's_ _\\ _g'
//123.123.123.123/path1/1\ -\ path2/path3\ path4/path5
</code>```

Using single quotes suppresses shell expansions (e.g. variables) and disables most escape sequences.

Body:
This command almost gives me what I want :-

echo "\\123.123.123.123\path1\1 - path2\path3 path4\path5" | sed 's_\\_/_g' | sed 's_ _\\ _g'
/123.123.123.123/path1/1\ -\ path2/path3\ path4/path5

But as one can see, its lost the '//' at the beginning!

ie, desired outout :-

//123.123.123.123/path1/1\ -\ path2/path3\ path4/path5

What am I missing?

Edit: After not testing the basics of echo (many thanks to all who pointed that out). I should of also been more clear on the end-game of this question.

I want to use this in a script, and define the windows path at the top.

How can I echo the path to a tmp file for sed?

This obviously wont work :-

WIN_PATH="\\123.123.123.123\path1\1 - path2\path3 path4\path5"
UNIX_PATH=`echo $WIN_PATH | sed 's_\\_/_g' | sed 's_ _\\ _g'`

Body:
Use single quotes instead of double quotes in echo - as it is the shell interprets your two backslashes as an escape sequence for \:

$ echo '\\123.123.123.123\path1\1 - path2\path3 path4\path5' | sed 's_\\_/_g' | sed 's_ _\\ _g'
//123.123.123.123/path1/1\ -\ path2/path3\ path4/path5

Using single quotes suppresses shell expansions (e.g. variables) and disables most escape sequences.


问:
How to use Expanded in SingleChildScrollView?
How to use Expanded in SingleChildScrollView? I have a screen with Image.network, ListView.builder and Row (TextFormField and IconButton). I wrapped ListView with Expanded. How to wrap this column with SingleChildScrollView? I need to move screen when the keyboard is open to see what I am writing. When I wrap my column I have this error.

      body: SingleChildScrollView(
        child: Column(
          children: <Widget>[
            Container(
              child: GestureDetector(
                child:
                Image.network(
                  postOne.imageUrl,
                  fit: BoxFit.fitWidth,
                  height: MediaQuery
                      .of(context)
                      .size
                      .width,
                  width: MediaQuery
                      .of(context)
                      .size
                      .width,
                ),
                onLongPress: () {},
                onDoubleTap: () {},
              ),
            ),
            Expanded(
              //height: MediaQuery.of(context).size.width*0.33,
              child: ListView.builder(
                  itemCount: commentList.length,
                  itemBuilder: (context, position) {
                    return GestureDetector(
                        onLongPress: () {},
                        child: Card(
                          child: Padding(
                            padding: EdgeInsets.all(5.0),
                            child: new CheckboxListTile(
                                title: new Text(commentList
                                    .elementAt(position)
                                    .coment,
                                  style: TextStyle(fontSize: 18.0),),
                                value: values[commentList
                                    .elementAt(position)
                                    .coment],
                                onChanged: (bool value) {}),
                          ),
                        )
                    );
                  }
              ),
            ),
            Container(
              child: Row(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    new Flexible(
                      child: Theme(
                        data: new ThemeData(
                            brightness: Brightness.light,
                            primarySwatch: Colors.grey,
                            inputDecorationTheme: new InputDecorationTheme(
                              labelStyle: new TextStyle(
                                  color: Colors.black45, fontSize: 18.0
                              ),
                            )
                        ),
                        child: new Form(
                          key: _formKey,
                          child: new TextFormField(
                            validator: (value) {
                              if (value.isEmpty) {
                                return 'Please enter the comment';
                              }
                            },
                            controller: commentController,
                            decoration: new InputDecoration(
                              labelText: "Add comment",
                              //hintText: 'Add comment'
                            ),
                            keyboardType: TextInputType.text,
                          ),
                        ),
                      ),
                    ),
                    new Container(
                        margin: EdgeInsets.only(left: 10.0, top: 12.0),
                        child: new IconButton(
                            icon: new Icon(Icons.send, color: Colors.black,),
                            onPressed: () {}
                        )
                    ),
                  ]),
            ),
          ],
        ),
      ),
```
```I/flutter ( 6816): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
I/flutter ( 6816): The following assertion was thrown during performLayout():
I/flutter ( 6816): RenderFlex children have non-zero flex but incoming height constraints are unbounded.
I/flutter ( 6816): When a column is in a parent that does not provide a finite height constraint, for example if it is
I/flutter ( 6816): in a vertical scrollable, it will try to shrink-wrap its children along the vertical axis. Setting a
I/flutter ( 6816): flex on a child (e.g. using Expanded) indicates that the child is to expand to fill the remaining
I/flutter ( 6816): space in the vertical direction.
I/flutter ( 6816): These two directives are mutually exclusive. If a parent is to shrink-wrap its child, the child
I/flutter ( 6816): cannot simultaneously expand to fit its parent.
I/flutter ( 6816): Consider setting mainAxisSize to MainAxisSize.min and using FlexFit.loose fits for the flexible
I/flutter ( 6816): children (using Flexible rather than Expanded). This will allow the flexible children to size
I/flutter ( 6816): themselves to less than the infinite remaining space they would otherwise be forced to take, and
I/flutter ( 6816): then will cause the RenderFlex to shrink-wrap the children rather than expanding to fit the maximum
I/flutter ( 6816): constraints provided by the parent.
I/flutter ( 6816): The affected RenderFlex is:
I/flutter ( 6816):   RenderFlex#9f534 relayoutBoundary=up11 NEEDS-LAYOUT NEEDS-PAINT
I/flutter ( 6816): The creator information is set to:
I/flutter ( 6816):   Column ← _SingleChildViewport ← IgnorePointer-[GlobalKey#3670d] ← Semantics ← Listener ←
I/flutter ( 6816):   _GestureSemantics ← RawGestureDetector-[LabeledGlobalKey<RawGestureDetectorState>#4878e] ←
I/flutter ( 6816):   Listener ← _ScrollableScope ← _ScrollSemantics-[GlobalKey#c5885] ← RepaintBoundary ← CustomPaint ←
I/flutter ( 6816):   ⋯
I/flutter ( 6816): The nearest ancestor providing an unbounded width constraint is:
I/flutter ( 6816):   _RenderSingleChildViewport#155d8 relayoutBoundary=up10 NEEDS-LAYOUT NEEDS-PAINT
I/flutter ( 6816):   creator: _SingleChildViewport ← IgnorePointer-[GlobalKey#3670d] ← Semantics ← Listener ←
I/flutter ( 6816):   _GestureSemantics ← RawGestureDetector-[LabeledGlobalKey<RawGestureDetectorState>#4878e] ←
I/flutter ( 6816):   Listener ← _ScrollableScope ← _ScrollSemantics-[GlobalKey#c5885] ← RepaintBoundary ← CustomPaint ←
I/flutter ( 6816):   RepaintBoundary ← ⋯
I/flutter ( 6816):   parentData: <none> (can use size)
I/flutter ( 6816):   constraints: BoxConstraints(0.0<=w<=440.8, 0.0<=h<=649.3)
I/flutter ( 6816):   size: MISSING
I/flutter ( 6816): See also: https://flutter.dev/layout/
I/flutter ( 6816): If this message did not help you determine the problem, consider using debugDumpRenderTree():
I/flutter ( 6816):   https://flutter.dev/debugging/#rendering-layer
I/flutter ( 6816):   http://docs.flutter.io/flutter/rendering/debugDumpRenderTree.html
I/flutter ( 6816): If none of the above helps enough to fix this problem, please don't hesitate to file a bug:
I/flutter ( 6816):   https://github.com/flutter/flutter/issues/new?template=BUG.md
I/flutter ( 6816):

```

答:
As already pointed out, because you are using a scrollable, you can't expand to the infinity (theoretically  speaking), that's what's happening when you try to expand your ListView that is nested in a SingleChildScrollView.

You can try using a NestedScrollView, or, if it fits your demands and because you have commented out this line:

```<code>//height: MediaQuery.of(context).size.width*0.33,
</code>```

You can just wrap your ListView in a ConstrainedBox (or even just a regular Container) with that height, for example, instead of the Expanded, like so:

```<code> Container(
         height: MediaQuery.of(context).size.width*0.33,
              child: ListView.builder(
                  itemCount: commentList.length,
                ...
               )
          )
</code>```

Since you are already in a scrollable, you shouldn't have issues with smaller screens, because the whole tree is scrollable.

Body:
How to use Expanded in SingleChildScrollView? I have a screen with Image.network, ListView.builder and Row (TextFormField and IconButton). I wrapped ListView with Expanded. How to wrap this column with SingleChildScrollView? I need to move screen when the keyboard is open to see what I am writing. When I wrap my column I have this error.

      body: SingleChildScrollView(
        child: Column(
          children: <Widget>[
            Container(
              child: GestureDetector(
                child:
                Image.network(
                  postOne.imageUrl,
                  fit: BoxFit.fitWidth,
                  height: MediaQuery
                      .of(context)
                      .size
                      .width,
                  width: MediaQuery
                      .of(context)
                      .size
                      .width,
                ),
                onLongPress: () {},
                onDoubleTap: () {},
              ),
            ),
            Expanded(
              //height: MediaQuery.of(context).size.width*0.33,
              child: ListView.builder(
                  itemCount: commentList.length,
                  itemBuilder: (context, position) {
                    return GestureDetector(
                        onLongPress: () {},
                        child: Card(
                          child: Padding(
                            padding: EdgeInsets.all(5.0),
                            child: new CheckboxListTile(
                                title: new Text(commentList
                                    .elementAt(position)
                                    .coment,
                                  style: TextStyle(fontSize: 18.0),),
                                value: values[commentList
                                    .elementAt(position)
                                    .coment],
                                onChanged: (bool value) {}),
                          ),
                        )
                    );
                  }
              ),
            ),
            Container(
              child: Row(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    new Flexible(
                      child: Theme(
                        data: new ThemeData(
                            brightness: Brightness.light,
                            primarySwatch: Colors.grey,
                            inputDecorationTheme: new InputDecorationTheme(
                              labelStyle: new TextStyle(
                                  color: Colors.black45, fontSize: 18.0
                              ),
                            )
                        ),
                        child: new Form(
                          key: _formKey,
                          child: new TextFormField(
                            validator: (value) {
                              if (value.isEmpty) {
                                return 'Please enter the comment';
                              }
                            },
                            controller: commentController,
                            decoration: new InputDecoration(
                              labelText: "Add comment",
                              //hintText: 'Add comment'
                            ),
                            keyboardType: TextInputType.text,
                          ),
                        ),
                      ),
                    ),
                    new Container(
                        margin: EdgeInsets.only(left: 10.0, top: 12.0),
                        child: new IconButton(
                            icon: new Icon(Icons.send, color: Colors.black,),
                            onPressed: () {}
                        )
                    ),
                  ]),
            ),
          ],
        ),
      ),

I/flutter ( 6816): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
I/flutter ( 6816): The following assertion was thrown during performLayout():
I/flutter ( 6816): RenderFlex children have non-zero flex but incoming height constraints are unbounded.
I/flutter ( 6816): When a column is in a parent that does not provide a finite height constraint, for example if it is
I/flutter ( 6816): in a vertical scrollable, it will try to shrink-wrap its children along the vertical axis. Setting a
I/flutter ( 6816): flex on a child (e.g. using Expanded) indicates that the child is to expand to fill the remaining
I/flutter ( 6816): space in the vertical direction.
I/flutter ( 6816): These two directives are mutually exclusive. If a parent is to shrink-wrap its child, the child
I/flutter ( 6816): cannot simultaneously expand to fit its parent.
I/flutter ( 6816): Consider setting mainAxisSize to MainAxisSize.min and using FlexFit.loose fits for the flexible
I/flutter ( 6816): children (using Flexible rather than Expanded). This will allow the flexible children to size
I/flutter ( 6816): themselves to less than the infinite remaining space they would otherwise be forced to take, and
I/flutter ( 6816): then will cause the RenderFlex to shrink-wrap the children rather than expanding to fit the maximum
I/flutter ( 6816): constraints provided by the parent.
I/flutter ( 6816): The affected RenderFlex is:
I/flutter ( 6816):   RenderFlex#9f534 relayoutBoundary=up11 NEEDS-LAYOUT NEEDS-PAINT
I/flutter ( 6816): The creator information is set to:
I/flutter ( 6816):   Column ← _SingleChildViewport ← IgnorePointer-[GlobalKey#3670d] ← Semantics ← Listener ←
I/flutter ( 6816):   _GestureSemantics ← RawGestureDetector-[LabeledGlobalKey<RawGestureDetectorState>#4878e] ←
I/flutter ( 6816):   Listener ← _ScrollableScope ← _ScrollSemantics-[GlobalKey#c5885] ← RepaintBoundary ← CustomPaint ←
I/flutter ( 6816):   ⋯
I/flutter ( 6816): The nearest ancestor providing an unbounded width constraint is:
I/flutter ( 6816):   _RenderSingleChildViewport#155d8 relayoutBoundary=up10 NEEDS-LAYOUT NEEDS-PAINT
I/flutter ( 6816):   creator: _SingleChildViewport ← IgnorePointer-[GlobalKey#3670d] ← Semantics ← Listener ←
I/flutter ( 6816):   _GestureSemantics ← RawGestureDetector-[LabeledGlobalKey<RawGestureDetectorState>#4878e] ←
I/flutter ( 6816):   Listener ← _ScrollableScope ← _ScrollSemantics-[GlobalKey#c5885] ← RepaintBoundary ← CustomPaint ←
I/flutter ( 6816):   RepaintBoundary ← ⋯
I/flutter ( 6816):   parentData: <none> (can use size)
I/flutter ( 6816):   constraints: BoxConstraints(0.0<=w<=440.8, 0.0<=h<=649.3)
I/flutter ( 6816):   size: MISSING
I/flutter ( 6816): See also: https://flutter.dev/layout/
I/flutter ( 6816): If this message did not help you determine the problem, consider using debugDumpRenderTree():
I/flutter ( 6816):   https://flutter.dev/debugging/#rendering-layer
I/flutter ( 6816):   http://docs.flutter.io/flutter/rendering/debugDumpRenderTree.html
I/flutter ( 6816): If none of the above helps enough to fix this problem, please don't hesitate to file a bug:
I/flutter ( 6816):   https://github.com/flutter/flutter/issues/new?template=BUG.md
I/flutter ( 6816):

Body:
As already pointed out, because you are using a scrollable, you can't expand to the infinity (theoretically  speaking), that's what's happening when you try to expand your ListView that is nested in a SingleChildScrollView.

You can try using a NestedScrollView, or, if it fits your demands and because you have commented out this line:

//height: MediaQuery.of(context).size.width*0.33,

You can just wrap your ListView in a ConstrainedBox (or even just a regular Container) with that height, for example, instead of the Expanded, like so:

 Container(
         height: MediaQuery.of(context).size.width*0.33,
              child: ListView.builder(
                  itemCount: commentList.length,
                ...
               )
          )

Since you are already in a scrollable, you shouldn't have issues with smaller screens, because the whole tree is scrollable.


问:
Remove item with header from angular material list
I have material list with header. Similar item grouped under header.
I added remove button also.in it. If I remove last item from list then the header also should remove. What I tried is below:

https://stackblitz.com/edit/angular-material-list-brenrk?file=app/app.component.ts

But it is not getting removed . Please help.

答:
You were really close to do it.

This is your application corrected and working:
https://stackblitz.com/edit/angular-material-list-bufnqr

To explain, it's better to call element.category in place of element['category'] and so on for every fields and you need to delete element.category and not element.name at the end when you remove the last item.


问:
How can I subscribe and unsubscribe from an observable?
I have two functions where I need to subscribe to an observable in the first one, and unsubscribe to it in the second. But in my code , I can't access the observable from the second function because it's not in its scope.

here are my functions :

```<code> start() {
    this.max = this.duration;
    const interval = Observable.interval(this.selectedSprint.duration);
    interval
      .takeWhile(_ => !this.isFinished)
      .do(i => this.current += 1)
      .subscribe();
    }

    stop() {
    // here I need to unsybscribe to the observable
    this.dialogService.openConfirmDialog('do you want to stop ?')
      .afterClosed().subscribe((result: boolean) => {
        if (result) {
    // if true logic
        }
      });
      }
</code>```

答:
Save a reference to your subscription in your class with this.sub = interval.[...].subscribe().

This way, you cann cal this.sub.unsubscribe() in your second function.

Body:
I have two functions where I need to subscribe to an observable in the first one, and unsubscribe to it in the second. But in my code , I can't access the observable from the second function because it's not in its scope.

here are my functions :

 start() {
    this.max = this.duration;
    const interval = Observable.interval(this.selectedSprint.duration);
    interval
      .takeWhile(_ => !this.isFinished)
      .do(i => this.current += 1)
      .subscribe();
    }

    stop() {
    // here I need to unsybscribe to the observable
    this.dialogService.openConfirmDialog('do you want to stop ?')
      .afterClosed().subscribe((result: boolean) => {
        if (result) {
    // if true logic
        }
      });
      }


问:
Is there an implicit default constructor in C++?
In the book I'm reading at the moment (C++ Without Fear) it says that if you don't declare a default constructor for a class, the compiler supplies one for you, which "zeroes out each data member". I've experimented with this, and I'm not seeing any zeroing -out behaviour. I also can't find anything that mentions this on Google. Is this just an error or a quirk of a specific compiler?</p>

答:
Zero-ing out only occurs for globals. So if your object is declared in the global scope, its members will be zero-ed out:</p>

```<code>class Blah
{
public:
    int x;
    int y;
};

Blah global;

int main(int argc, char **argv) {
    Blah local;
    cout<<global.x<<endl;  // will be 0
    cout<<local.x<<endl;   // will be random
}
</code>```

OwnerDisplayName: Skilldrick

ContentLicense: CC BY-SA 2.5

Body:
Zero-ing out only occurs for globals. So if your object is declared in the global scope, its members will be zero-ed out:

class Blah
{
public:
    int x;
    int y;
};

Blah global;

int main(int argc, char **argv) {
    Blah local;
    cout<<global.x<<endl;  // will be 0
    cout<<local.x<<endl;   // will be random
}

OwnerDisplayName: codelogic


问:
apparently same commits give different sha1, why?
After re-write of a subtree history from a repository with a script of mine, I compared it with what would do a git filter-branch ... on that same subtree. I see that initial commits have different sha1 although I expected them to be identical (consequence of this is that all commits from both histories have different sha1).

Doing a git show --format=raw <commit-sha1> on both commits gives exactly the same output (except for first line, which is commit <commit-sha1>, introducing the result).

Object files are completely different, but as they are binaries, I can't figure out the root cause.

Assuming all git versions are consistent with each other, what could explain to have 2 different sha1?

Thank you

答:
Git's inputs to a commit hash include metadata such as the SHA1 of the tree, the SHA1 of the parent, the commiter's name, email and commit date, and the author's name, email and commit date. So when you rewrote history, the commiter commit date and the tree (since you did a filter-branch) have probably changed, hence the difference in your commit's SHA1.

For more information about the format of a commit, you can use git cat-file commit <sha>, or look up the Git Objects section of the Git Book.


问:
Inside of Worker class call BroadcastReceiver class
As for my requirement I would like to call inside of Worker class call BroadcastReceiver class , any one please give some suggestions.

```<code>// BroadcastReceiver sample class
public class NetworkChangeReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i("??????","Working fine");
    }
}

// workers class
class WorkSample(context: Context, workerParams: WorkerParameters) :  Worker(context, workerParams) {
    override fun doWork(): Result {

       // BroadcastReceiver class
         NetworkChangeReceiver()

         return Result.success()
     }

 }

//Activity
button.setOnClickListener {
     // request of workmanager
     val constraints  = Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build()

     val OneTimeWorkRequest = OneTimeWorkRequest.Builder(WorkSample::class.java).setConstraints(constraints).build()
     WorkManager.getInstance().enqueue(OneTimeWorkRequest)
}
</code>```

答:
You can call inside of doWork() method ,

```<code>override fun doWork(): Result {
     val i = Intent(applicationContext, NetworkChangeReceiver::class.java)
     applicationContext.sendBroadcast(i)

     return Result.success()
}
</code>```

Body:
As for my requirement I would like to call inside of Worker class call BroadcastReceiver class , any one please give some suggestions.

// BroadcastReceiver sample class
public class NetworkChangeReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i("??????","Working fine");
    }
}

// workers class
class WorkSample(context: Context, workerParams: WorkerParameters) :  Worker(context, workerParams) {
    override fun doWork(): Result {

       // BroadcastReceiver class
         NetworkChangeReceiver()

         return Result.success()
     }

 }

//Activity
button.setOnClickListener {
     // request of workmanager
     val constraints  = Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build()

     val OneTimeWorkRequest = OneTimeWorkRequest.Builder(WorkSample::class.java).setConstraints(constraints).build()
     WorkManager.getInstance().enqueue(OneTimeWorkRequest)
}

Body:
You can call inside of doWork() method ,

override fun doWork(): Result {
     val i = Intent(applicationContext, NetworkChangeReceiver::class.java)
     applicationContext.sendBroadcast(i)

     return Result.success()
}


问:
Possible to do a pivot outside of BigQuery?
Let's say I'm looking to build the following pivot table:

```<code>// count by age

 age     male     female
 1-25    18       23
 26-100  19       10
</code>```

To do this, I can do a basic aggregation like this:

```<code>SELECT age, gender, count(*) GROUP BY age, gender
</code>```

And get results such as:

```<code>gender   age    count
male     1-25   18
male     26-100 19
male     1-25   23
male     26-100 10
</code>```

And then I can 'build the results' outside of BigQuery/SQL (such as in javascript or even pandas) to get the pivoted result.

However, I run into trouble when the values can't be simply "added up" or calculated in some straightforward fashion. For example:

```<code>// distinct users by country

country    male       female
us         192,293    64,000
jp         1,203,203  1,000,000
</code>```

Is there a way to grab a value in BigQuery so that we can do this calculation outside of BigQuery? I've posted a preceding question to this here where it seems like you cannot use the HLL_COUNT, as that's not available outside. [Or is there some other type of algorithm that can be applied to build some sort of unique sketch that can be merged outside SQL?].

Or is there another approach to building pivot results (outside of BigQuery) that I'm missing?

Update: The above examples are more to give an overview of the issue. The actual pivot queries would be like this: Get the top patent countries, codes in a BQ public dataset, on both the X and Y axis.

答:
I don't understand.  Why not do this inside BigQuery?

```<code>SELECT age,
       COUNTIF( gender = 'male' ) as males,
       COUNTIF( gender = 'female' ) as females
GROUP BY age;
</code>```

Body:
Let's say I'm looking to build the following pivot table:

// count by age

 age     male     female
 1-25    18       23
 26-100  19       10

To do this, I can do a basic aggregation like this:

SELECT age, gender, count(*) GROUP BY age, gender

And get results such as:

gender   age    count
male     1-25   18
male     26-100 19
male     1-25   23
male     26-100 10

And then I can 'build the results' outside of BigQuery/SQL (such as in javascript or even pandas) to get the pivoted result.

However, I run into trouble when the values can't be simply "added up" or calculated in some straightforward fashion. For example:

// distinct users by country

country    male       female
us         192,293    64,000
jp         1,203,203  1,000,000

Is there a way to grab a value in BigQuery so that we can do this calculation outside of BigQuery? I've posted a preceding question to this here where it seems like you cannot use the HLL_COUNT, as that's not available outside. [Or is there some other type of algorithm that can be applied to build some sort of unique sketch that can be merged outside SQL?].

Or is there another approach to building pivot results (outside of BigQuery) that I'm missing?

Update: The above examples are more to give an overview of the issue. The actual pivot queries would be like this: Get the top patent countries, codes in a BQ public dataset, on both the X and Y axis.

Body:
I don't understand.  Why not do this inside BigQuery?

SELECT age,
       COUNTIF( gender = 'male' ) as males,
       COUNTIF( gender = 'female' ) as females
GROUP BY age;


问:
guzzle getbody function accessing the diffrenet elements of response
i am using guzzle to post some data to some api and recive some data back here is my code :

```<code>  $response = $client->request('POST', 'http://url/api/v1/transaction/Verify', [
        'headers' => ['Content-Type' => 'application/json'],
        'body' => '{
        "tn":"1905463527",
        }'
    ]);
        $responebody = $response->getBody();
</code>```

i exacly dont know if i am getting string or object when ever i use getbody of guzzle but here is what i get when i echo the response :

```<code>{"errorCode":null,"errorMessage":"Canceled by user.","succeed":false,"tn":1905463527,"verifyCount":35,"amount":10000}
</code>```

now here for example i want to access the "succeed " element and i want to know how can i access to check if it is true or not ,

答:
You should check the Content-Type header and if it's application/json you can run json_decode on the body. Take this as an example

```<code>if ($response->getContentType() == 'application/json') {
    $responseBody = json_decode($response->getContent());
    // now you can access $responseBody->succeed
    ...
}
</code>```

Body:
i am using guzzle to post some data to some api and recive some data back here is my code :

  $response = $client->request('POST', 'http://url/api/v1/transaction/Verify', [
        'headers' => ['Content-Type' => 'application/json'],
        'body' => '{
        "tn":"1905463527",
        }'
    ]);
        $responebody = $response->getBody();

i exacly dont know if i am getting string or object when ever i use getbody of guzzle but here is what i get when i echo the response :

{"errorCode":null,"errorMessage":"Canceled by user.","succeed":false,"tn":1905463527,"verifyCount":35,"amount":10000}

now here for example i want to access the "succeed " element and i want to know how can i access to check if it is true or not ,

Body:
You should check the Content-Type header and if it's application/json you can run json_decode on the body. Take this as an example

if ($response->getContentType() == 'application/json') {
    $responseBody = json_decode($response->getContent());
    // now you can access $responseBody->succeed
    ...
}


问:
how to assign value in List<T> type Xml class
I want to assign value in List. i am not able to understand how can i assign value in List under Stops node. Can you please tell me how can i do this.Below is the code with class file

Created class from XML

```<code>[XmlRoot(ElementName="Customer")]
    public class Customer {
        [XmlAttribute(AttributeName="CustomerID")]
        public string CustomerID { get; set; }
        [XmlAttribute(AttributeName="CustomerCode")]
        public string CustomerCode { get; set; }
        [XmlAttribute(AttributeName="Name")]
        public string Name { get; set; }
        [XmlAttribute(AttributeName="Address")]
        public string Address { get; set; }
    }

    [XmlRoot(ElementName="OrderStopPiece")]
    public class OrderStopPiece {
        [XmlAttribute(AttributeName="Sequence")]
        public string Sequence { get; set; }
        [XmlAttribute(AttributeName="PieceAction")]
        public string PieceAction { get; set; }
    }

    [XmlRoot(ElementName="OrderStopPieces")]
    public class OrderStopPieces {
        [XmlElement(ElementName="OrderStopPiece")]
        public OrderStopPiece OrderStopPiece { get; set; }
    }

    [XmlRoot(ElementName="Stop")]
    public class Stop {
        [XmlElement(ElementName="OrderStopPieces")]
        public OrderStopPieces OrderStopPieces { get; set; }
        [XmlAttribute(AttributeName="Sequence")]
        public string Sequence { get; set; }
        [XmlAttribute(AttributeName="StopType")]
        public string StopType { get; set; }
        [XmlAttribute(AttributeName="Note")]
        public string Note { get; set; }
        [XmlAttribute(AttributeName="Name")]
        public string Name { get; set; }
    }

    [XmlRoot(ElementName="Stops")]
    public class Stops {
        [XmlElement(ElementName="Stop")]
        public List<Stop> Stop { get; set; }
    }

    [XmlRoot(ElementName="Order")]
    public class Order {
        [XmlElement(ElementName="Customer")]
        public Customer Customer { get; set; }
        [XmlElement(ElementName="Stops")]
        public Stops Stops { get; set; }
        [XmlAttribute(AttributeName="UserID")]
        public string UserID { get; set; }
        [XmlAttribute(AttributeName="Notes")]
        public string Notes { get; set; }
        [XmlAttribute(AttributeName="CustomerID")]
        public string CustomerID { get; set; }
    }

    [XmlRoot(ElementName="SaveOrder", Namespace="http://www.uBB.com/schemas/")]
    public class SaveOrder {
        [XmlElement(ElementName="Order")]
        public Order Order { get; set; }
    }

    [XmlRoot(ElementName="Body", Namespace="http://schemas.xmlsoap.org/soap/envelope/")]
    public class Body {
        [XmlElement(ElementName="SaveOrder", Namespace="http://www.uBB.com/schemas/")]
        public SaveOrder SaveOrder { get; set; }
        [XmlAttribute(AttributeName="UserGUID")]
        public string UserGUID { get; set; }
    }

    [XmlRoot(ElementName="Envelope", Namespace="http://schemas.xmlsoap.org/soap/envelope/")]
    public class Envelope {
        [XmlElement(ElementName="Body", Namespace="http://schemas.xmlsoap.org/soap/envelope/")]
        public Body Body { get; set; }
        [XmlAttribute(AttributeName="m", Namespace="http://www.w3.org/2000/xmlns/")]
        public string M { get; set; }
        [XmlAttribute(AttributeName="SOAP", Namespace="http://www.w3.org/2000/xmlns/")]
        public string SOAP { get; set; }
    }
</code>```

Code where i am assiging other values

```<code>var SaveOrder = new ECSaveOrderRequest.Envelope
                {
                    Body = new ECSaveOrderRequest.Body
                    {
                        UserGUID = guid,
                        SaveOrder = new ECSaveOrderRequest.SaveOrder
                        {
                            Order = new ECSaveOrderRequest.Order
                            {
                                UserID = Uid,
                                Notes = "",
                                CustomerID = "",
                                Customer = new ECSaveOrderRequest.Customer
                                {
                                    CustomerID = "",
                                    CustomerCode = "",
                                    Name = "",
                                    Address = "",
                                    City = ""
                                },
                                Stops = new ECSaveOrderRequest.Stops()
                                {
                                    Stop = new List<ECSaveOrderRequest.Stop>()
                                    {
                                                /*  Here i want to Assign value in List<stop> */
                                    },

                                },
                                Jobs = new ECSaveOrderRequest.Jobs()
                                {
                                    Job = new ECSaveOrderRequest.Job()
                                    {
                                        Sequence=""
                                    }
                                }
                            },
                        }

                     }
                    };
</code>```

答:
You can do the following.

```<code>Stops = new ECSaveOrderRequest.Stops()
                                {
                                    Stop = new List<ECSaveOrderRequest.Stop>
                                    {
                                        new ECSaveOrderRequest.Stop                                         {
                                            Sequence = "",
                                            StopType = ""
                                            // rest of properties
                                        },
                                        new ECSaveOrderRequest.Stop                                         {
                                            Sequence = "",
                                            StopType = ""
                                            // rest of properties
                                        },
                                    }

                                },
</code>```

But a better (more readable) solution would be create the List of Stop first and then assign it to Stops.Stop.

```<code>Stops = new ECSaveOrderRequest.Stops()
                                {
                                 Stop = listOfStops
                                }
</code>```

Body:
I want to assign value in List. i am not able to understand how can i assign value in List under Stops node. Can you please tell me how can i do this.Below is the code with class file

Created class from XML

[XmlRoot(ElementName="Customer")]
    public class Customer {
        [XmlAttribute(AttributeName="CustomerID")]
        public string CustomerID { get; set; }
        [XmlAttribute(AttributeName="CustomerCode")]
        public string CustomerCode { get; set; }
        [XmlAttribute(AttributeName="Name")]
        public string Name { get; set; }
        [XmlAttribute(AttributeName="Address")]
        public string Address { get; set; }
    }

    [XmlRoot(ElementName="OrderStopPiece")]
    public class OrderStopPiece {
        [XmlAttribute(AttributeName="Sequence")]
        public string Sequence { get; set; }
        [XmlAttribute(AttributeName="PieceAction")]
        public string PieceAction { get; set; }
    }

    [XmlRoot(ElementName="OrderStopPieces")]
    public class OrderStopPieces {
        [XmlElement(ElementName="OrderStopPiece")]
        public OrderStopPiece OrderStopPiece { get; set; }
    }

    [XmlRoot(ElementName="Stop")]
    public class Stop {
        [XmlElement(ElementName="OrderStopPieces")]
        public OrderStopPieces OrderStopPieces { get; set; }
        [XmlAttribute(AttributeName="Sequence")]
        public string Sequence { get; set; }
        [XmlAttribute(AttributeName="StopType")]
        public string StopType { get; set; }
        [XmlAttribute(AttributeName="Note")]
        public string Note { get; set; }
        [XmlAttribute(AttributeName="Name")]
        public string Name { get; set; }
    }

    [XmlRoot(ElementName="Stops")]
    public class Stops {
        [XmlElement(ElementName="Stop")]
        public List<Stop> Stop { get; set; }
    }

    [XmlRoot(ElementName="Order")]
    public class Order {
        [XmlElement(ElementName="Customer")]
        public Customer Customer { get; set; }
        [XmlElement(ElementName="Stops")]
        public Stops Stops { get; set; }
        [XmlAttribute(AttributeName="UserID")]
        public string UserID { get; set; }
        [XmlAttribute(AttributeName="Notes")]
        public string Notes { get; set; }
        [XmlAttribute(AttributeName="CustomerID")]
        public string CustomerID { get; set; }
    }

    [XmlRoot(ElementName="SaveOrder", Namespace="http://www.uBB.com/schemas/")]
    public class SaveOrder {
        [XmlElement(ElementName="Order")]
        public Order Order { get; set; }
    }

    [XmlRoot(ElementName="Body", Namespace="http://schemas.xmlsoap.org/soap/envelope/")]
    public class Body {
        [XmlElement(ElementName="SaveOrder", Namespace="http://www.uBB.com/schemas/")]
        public SaveOrder SaveOrder { get; set; }
        [XmlAttribute(AttributeName="UserGUID")]
        public string UserGUID { get; set; }
    }

    [XmlRoot(ElementName="Envelope", Namespace="http://schemas.xmlsoap.org/soap/envelope/")]
    public class Envelope {
        [XmlElement(ElementName="Body", Namespace="http://schemas.xmlsoap.org/soap/envelope/")]
        public Body Body { get; set; }
        [XmlAttribute(AttributeName="m", Namespace="http://www.w3.org/2000/xmlns/")]
        public string M { get; set; }
        [XmlAttribute(AttributeName="SOAP", Namespace="http://www.w3.org/2000/xmlns/")]
        public string SOAP { get; set; }
    }

Code where i am assiging other values

var SaveOrder = new ECSaveOrderRequest.Envelope
                {
                    Body = new ECSaveOrderRequest.Body
                    {
                        UserGUID = guid,
                        SaveOrder = new ECSaveOrderRequest.SaveOrder
                        {
                            Order = new ECSaveOrderRequest.Order
                            {
                                UserID = Uid,
                                Notes = "",
                                CustomerID = "",
                                Customer = new ECSaveOrderRequest.Customer
                                {
                                    CustomerID = "",
                                    CustomerCode = "",
                                    Name = "",
                                    Address = "",
                                    City = ""
                                },
                                Stops = new ECSaveOrderRequest.Stops()
                                {
                                    Stop = new List<ECSaveOrderRequest.Stop>()
                                    {
                                                /*  Here i want to Assign value in List<stop> */
                                    },

                                },
                                Jobs = new ECSaveOrderRequest.Jobs()
                                {
                                    Job = new ECSaveOrderRequest.Job()
                                    {
                                        Sequence=""
                                    }
                                }
                            },
                        }

                     }
                    };

Body:
You can do the following.

Stops = new ECSaveOrderRequest.Stops()
                                {
                                    Stop = new List<ECSaveOrderRequest.Stop>
                                    {
                                        new ECSaveOrderRequest.Stop                                         {
                                            Sequence = "",
                                            StopType = ""
                                            // rest of properties
                                        },
                                        new ECSaveOrderRequest.Stop                                         {
                                            Sequence = "",
                                            StopType = ""
                                            // rest of properties
                                        },
                                    }

                                },

But a better (more readable) solution would be create the List of Stop first and then assign it to Stops.Stop.

Stops = new ECSaveOrderRequest.Stops()
                                {
                                 Stop = listOfStops
                                }


问:
How to implement horizontal stacked cards which moves from left to right when we swipe?
I want to show horizontal stacked cards , which moves one by one from left to right by swipe action . Once a card moves it forms a stack on the right side

I have tried seeing various libraries which straight away does not implement this. https://www.cocoacontrols.com/controls/iaccordion this one came close it has vertical swipe and is in objective C. Can you point me in the right direction to get this done ?

答:
Card-like stacks are very easy to make but can be hard to perfect when it comes to some effects. Basically each of your views has one of 3 possible positions; on initial stack, on target stack, user is dragging it.

So the simplest implementation is to define 2 centers for your views and have 2 arrays of views. At the beginning all the views are in the first array. All views in first array should be centered to first center and in second array centered to the second center. Now you need a pan gesture. When a gesture starts you should check if it starts on the left stack if it does simply remove it from first array and begin changing its center. Like

```<code>func onPanGesture(_ sender: UIGestureRecognizer) {
    switch sender.state {
    case .began:
        if leftStackView.bounds.contains(sender.location(in: leftStackView)), viewsInLeftStack.count > 0 {
            pannedView = viewsInLeftStack.removeLast()
        }
    case .changed:
        pannedView?.center = sender.location(in: self.view)
    }
}
</code>```

Now when finger is lifted you should check if card should be put back or moved to the other stack. So another case for gesture recognizer must be added:

```<code>    case .ended, .cancelled:
        if let pannedView = pannedView {
            if(abs(pannedView.center.x-leftStackView.center.x) > abs(pannedView.center.x-rightStackView.center.x)) {
                // Closer to the right one horizontally
                viewsInLeftStack.append(pannedView)
                pannedView.center = leftStackView.center
            } else {
                // Closer to the left one horizontally
                viewsInRightStack.append(pannedView)
                pannedView.center = rightStackView.center
            }
        }
</code>```

In basics that is all you need. But then comes making the component nice. For instance when card is released it should animate to its deck:

```<code>UIView.animate(withDuration: 0.3) {
    pannedView.center = self.rightStackView.center
}
</code>```

Then cards may be a bit displaced on both of decks which is easiest to apply some transform. They may even rotate a bit as you drag them... But this is all up to you what you want to implement.

Body:
Card-like stacks are very easy to make but can be hard to perfect when it comes to some effects. Basically each of your views has one of 3 possible positions; on initial stack, on target stack, user is dragging it.

So the simplest implementation is to define 2 centers for your views and have 2 arrays of views. At the beginning all the views are in the first array. All views in first array should be centered to first center and in second array centered to the second center. Now you need a pan gesture. When a gesture starts you should check if it starts on the left stack if it does simply remove it from first array and begin changing its center. Like

func onPanGesture(_ sender: UIGestureRecognizer) {
    switch sender.state {
    case .began:
        if leftStackView.bounds.contains(sender.location(in: leftStackView)), viewsInLeftStack.count > 0 {
            pannedView = viewsInLeftStack.removeLast()
        }
    case .changed:
        pannedView?.center = sender.location(in: self.view)
    }
}

Now when finger is lifted you should check if card should be put back or moved to the other stack. So another case for gesture recognizer must be added:

    case .ended, .cancelled:
        if let pannedView = pannedView {
            if(abs(pannedView.center.x-leftStackView.center.x) > abs(pannedView.center.x-rightStackView.center.x)) {
                // Closer to the right one horizontally
                viewsInLeftStack.append(pannedView)
                pannedView.center = leftStackView.center
            } else {
                // Closer to the left one horizontally
                viewsInRightStack.append(pannedView)
                pannedView.center = rightStackView.center
            }
        }

In basics that is all you need. But then comes making the component nice. For instance when card is released it should animate to its deck:

UIView.animate(withDuration: 0.3) {
    pannedView.center = self.rightStackView.center
}

Then cards may be a bit displaced on both of decks which is easiest to apply some transform. They may even rotate a bit as you drag them... But this is all up to you what you want to implement.


答:
One solution is to store the subscription in your component.

export class Component {
  interval$: Subscription;

  start() {
    this.max = this.duration;
    this.interval$ = Observable.interval(this.selectedSprint.duration)
      .takeWhile(_ => !this.isFinished)
      .do(i => this.current += 1)
      .subscribe();
  }

  stop() {
    // here I need to unsybscribe to the observable
    this.dialogService.openConfirmDialog('do you want to stop ?')
      .afterClosed().subscribe((result: boolean) => {
        if (result) {
          this.interval$.unsubscribe();
        }
    });
  }
}
```

<p><strong>EDIT to answer OP's comment</strong></p>

<pre class="lang-js prettyprint-override"><code>export class Component {
  intervalSub$: Subscription;
  intervalObs: Observable<number>;

  start() {
    this.max = this.duration;
    this.intervalObs$ = Observable.interval(this.selectedSprint.duration)
      .takeWhile(_ => !this.isFinished)
      .do(i => this.current += 1);
   this.intervalSub$ = intervalObs.subscribe();
  }

  stop() {
    // here I need to unsybscribe to the observable
    this.dialogService.openConfirmDialog('do you want to stop ?')
      .afterClosed().subscribe((result: boolean) => {
        if (result) {
          this.intervalSub$.unsubscribe();
        }
    });
  }
  /**
   * If you unsubscribed from the interval and you want to resume
   * (If this.isFinished is true, it won't do a thing)
   */
  resume() {
    this.intervalObs.subscribe();
  }
}
</code>```

Title: How can I subscribe and unsubscribe from an observable?

Body:
One solution is to store the subscription in your component.

export class Component {
  interval$: Subscription;

  start() {
    this.max = this.duration;
    this.interval$ = Observable.interval(this.selectedSprint.duration)
      .takeWhile(_ => !this.isFinished)
      .do(i => this.current += 1)
      .subscribe();
  }

  stop() {
    // here I need to unsybscribe to the observable
    this.dialogService.openConfirmDialog('do you want to stop ?')
      .afterClosed().subscribe((result: boolean) => {
        if (result) {
          this.interval$.unsubscribe();
        }
    });
  }
}

EDIT to answer OP's comment

export class Component {
  intervalSub$: Subscription;
  intervalObs: Observable<number>;

  start() {
    this.max = this.duration;
    this.intervalObs$ = Observable.interval(this.selectedSprint.duration)
      .takeWhile(_ => !this.isFinished)
      .do(i => this.current += 1);
   this.intervalSub$ = intervalObs.subscribe();
  }

  stop() {
    // here I need to unsybscribe to the observable
    this.dialogService.openConfirmDialog('do you want to stop ?')
      .afterClosed().subscribe((result: boolean) => {
        if (result) {
          this.intervalSub$.unsubscribe();
        }
    });
  }
  /**
   * If you unsubscribed from the interval and you want to resume
   * (If this.isFinished is true, it won't do a thing)
   */
  resume() {
    this.intervalObs.subscribe();
  }
}


问:
Pandas date range returns "could not convert string to Timestamp" for yyyy-ww
I have a dataframe with two columns; Sales and Date.

```<code>dataset.head(10)

        Date    Sales
0   2015-01-02  34988.0
1   2015-01-03  32809.0
2   2015-01-05  9802.0
3   2015-01-06  15124.0
4   2015-01-07  13553.0
5   2015-01-08  14574.0
6   2015-01-09  20836.0
7   2015-01-10  28825.0
8   2015-01-12  6938.0
9   2015-01-13  11790.0
</code>```

I want to convert the Date column from yyyy-mm-dd (e.g. 2015-06-01) to yyyy-ww (e.g. 2015-23), so I run the following piece of code:

```<code>dataset["Date"] = pd.to_datetime(dataset["Date"]).dt.strftime('%Y-%V')
</code>```

Then I group by my Sales based on weeks, i.e.

```<code>data = dataset.groupby(['Date'])["Sales"].sum().reset_index()

data.head(10)

    Date    Sales
0   2015-01 67797.0
1   2015-02 102714.0
2   2015-03 107011.0
3   2015-04 121480.0
4   2015-05 148098.0
5   2015-06 132152.0
6   2015-07 133914.0
7   2015-08 136160.0
8   2015-09 185471.0
9   2015-10 190793.0
</code>```

Now I want to create a date range based on the Date column, since I'm predicting sales based on weeks:

```<code>ds = data.Date.values
ds_pred = pd.date_range(start=ds.min(), periods=len(ds) + num_pred_weeks,
freq="W")
</code>```

However I'm getting the following error: could not convert string to Timestamp which I'm not really sure how to fix. So, if I use 2015-01-01 as the starting date of my date-import I get no error, which makes me realize that I'm using the functions wrong. However, I'm not sure how?

I would like to basically have a date range that spans weekly from the current week and then 52 weeks into the future.

答:
I think problem is want create minimum of dataset["Date"] column filled by strings in format YYYY-VV. But for pass to date_range need format YYYY-MM-DD or datetime object.

I found this:

Several additional directives not required by the C89 standard are included for convenience. These parameters all correspond to ISO 8601 date values. These may not be available on all platforms when used with the strftime() method. The ISO 8601 year and ISO 8601 week directives are not interchangeable with the year and week number directives above. Calling strptime() with incomplete or ambiguous ISO 8601 directives will raise a ValueError.

%V ISO 8601 week as a decimal number with Monday as the first day of the week. Week 01 is the week containing Jan 4.

Pandas 0.24.2 bug with YYYY-VV format:

```<code>dataset = pd.DataFrame({'Date':['2015-06-01','2015-06-02']})

dataset["Date"] = pd.to_datetime(dataset["Date"]).dt.strftime('%Y-%V')
print (dataset)
      Date
0  2015-23
1  2015-23

ds = pd.to_datetime(dataset['Date'], format='%Y-%V')
print (ds)
</code>```

ValueError: 'V' is a bad directive in format '%Y-%V'

Possible solution is use %U or %W, check this:

%U Week number of the year (Sunday as the first day of the week) as a zero padded decimal number. All days in a new year preceding the first Sunday are considered to be in week 0.

%W Week number of the year (Monday as the first day of the week) as a decimal number. All days in a new year preceding the first Monday are considered to be in week 0.

```<code>dataset = pd.DataFrame({'Date':['2015-06-01','2015-06-02']})

dataset["Date"] = pd.to_datetime(dataset["Date"]).dt.strftime('%Y-%U')
print (dataset)
      Date
0  2015-22
1  2015-22

ds = pd.to_datetime(dataset['Date'] + '-1', format='%Y-%U-%w')
print (ds)
0   2015-06-01
1   2015-06-01
Name: Date, dtype: datetime64[ns]
</code>```

Or using data from original DataFrame in datetimes:

```<code>dataset = pd.DataFrame({'Date':['2015-06-01','2015-06-02'],
                        'Sales':[10,20]})

dataset["Date"] = pd.to_datetime(dataset["Date"])
print (dataset)
        Date  Sales
0 2015-06-01     10
1 2015-06-02     20

data = dataset.groupby(dataset['Date'].dt.strftime('%Y-%V'))["Sales"].sum().reset_index()
print (data)
      Date  Sales
0  2015-23     30

num_pred_weeks = 5
ds = data.Date.values
ds_pred = pd.date_range(start=dataset["Date"].min(), periods=len(ds) + num_pred_weeks, freq="W")
print (ds_pred)
DatetimeIndex(['2015-06-07', '2015-06-14', '2015-06-21',
               '2015-06-28',
               '2015-07-05', '2015-07-12'],
              dtype='datetime64[ns]', freq='W-SUN')
</code>```

Body:
I have a dataframe with two columns; Sales and Date.

dataset.head(10)

        Date    Sales
0   2015-01-02  34988.0
1   2015-01-03  32809.0
2   2015-01-05  9802.0
3   2015-01-06  15124.0
4   2015-01-07  13553.0
5   2015-01-08  14574.0
6   2015-01-09  20836.0
7   2015-01-10  28825.0
8   2015-01-12  6938.0
9   2015-01-13  11790.0

I want to convert the Date column from yyyy-mm-dd (e.g. 2015-06-01) to yyyy-ww (e.g. 2015-23), so I run the following piece of code:

dataset["Date"] = pd.to_datetime(dataset["Date"]).dt.strftime('%Y-%V')

Then I group by my Sales based on weeks, i.e.

data = dataset.groupby(['Date'])["Sales"].sum().reset_index()

data.head(10)

    Date    Sales
0   2015-01 67797.0
1   2015-02 102714.0
2   2015-03 107011.0
3   2015-04 121480.0
4   2015-05 148098.0
5   2015-06 132152.0
6   2015-07 133914.0
7   2015-08 136160.0
8   2015-09 185471.0
9   2015-10 190793.0

Now I want to create a date range based on the Date column, since I'm predicting sales based on weeks:

ds = data.Date.values
ds_pred = pd.date_range(start=ds.min(), periods=len(ds) + num_pred_weeks,
freq="W")

However I'm getting the following error: could not convert string to Timestamp which I'm not really sure how to fix. So, if I use 2015-01-01 as the starting date of my date-import I get no error, which makes me realize that I'm using the functions wrong. However, I'm not sure how?

I would like to basically have a date range that spans weekly from the current week and then 52 weeks into the future.

Body:
I think problem is want create minimum of dataset["Date"] column filled by strings in format YYYY-VV. But for pass to date_range need format YYYY-MM-DD or datetime object.

I found this:

Several additional directives not required by the C89 standard are included for convenience. These parameters all correspond to ISO 8601 date values. These may not be available on all platforms when used with the strftime() method. The ISO 8601 year and ISO 8601 week directives are not interchangeable with the year and week number directives above. Calling strptime() with incomplete or ambiguous ISO 8601 directives will raise a ValueError.

%V ISO 8601 week as a decimal number with Monday as the first day of the week. Week 01 is the week containing Jan 4.

Pandas 0.24.2 bug with YYYY-VV format:

dataset = pd.DataFrame({'Date':['2015-06-01','2015-06-02']})

dataset["Date"] = pd.to_datetime(dataset["Date"]).dt.strftime('%Y-%V')
print (dataset)
      Date
0  2015-23
1  2015-23

ds = pd.to_datetime(dataset['Date'], format='%Y-%V')
print (ds)

ValueError: 'V' is a bad directive in format '%Y-%V'

Possible solution is use %U or %W, check this:

%U Week number of the year (Sunday as the first day of the week) as a zero padded decimal number. All days in a new year preceding the first Sunday are considered to be in week 0.

%W Week number of the year (Monday as the first day of the week) as a decimal number. All days in a new year preceding the first Monday are considered to be in week 0.

dataset = pd.DataFrame({'Date':['2015-06-01','2015-06-02']})

dataset["Date"] = pd.to_datetime(dataset["Date"]).dt.strftime('%Y-%U')
print (dataset)
      Date
0  2015-22
1  2015-22

ds = pd.to_datetime(dataset['Date'] + '-1', format='%Y-%U-%w')
print (ds)
0   2015-06-01
1   2015-06-01
Name: Date, dtype: datetime64[ns]

Or using data from original DataFrame in datetimes:

dataset = pd.DataFrame({'Date':['2015-06-01','2015-06-02'],
                        'Sales':[10,20]})

dataset["Date"] = pd.to_datetime(dataset["Date"])
print (dataset)
        Date  Sales
0 2015-06-01     10
1 2015-06-02     20

data = dataset.groupby(dataset['Date'].dt.strftime('%Y-%V'))["Sales"].sum().reset_index()
print (data)
      Date  Sales
0  2015-23     30

num_pred_weeks = 5
ds = data.Date.values
ds_pred = pd.date_range(start=dataset["Date"].min(), periods=len(ds) + num_pred_weeks, freq="W")
print (ds_pred)
DatetimeIndex(['2015-06-07', '2015-06-14', '2015-06-21',
               '2015-06-28',
               '2015-07-05', '2015-07-12'],
              dtype='datetime64[ns]', freq='W-SUN')