问:
MATLAB: What's wrong with my quatrotate script?
My version of MATLAB doesn't have the quatrotate function included, so I wrote my own using the equation MathWorks provide here. Trouble is, I don't get the same answers they get in their example in my function, or when I hand calculate it.

Under their example if I input the following I should get an n vector [-1 1 1]:

q = [1 0 1 0]; r = [1 1 1]; n = quatrotate(q, r)

n =

-1.0000    1.0000    1.0000

In my function, and by hand, I get:

[-3 1 1]

What am I missing here? The more I search the more confused I get. As far as I can tell the answer should be [-3 1 1].

Here is the function I wrote:

```<code>function [n] = quatrotate(q,r)
%Rotate a given acceleration vector by a given quaternion
%
%Inputs:
% q:      A matrix containing a set of quaternion vectors of the
%         form q = [w,x,y,z]
% r:      A matrix containing a set of linear acceleration vectors
%         of the form r= [i,j,k] (also known as [x,y,z])
%
% Outputs:
% n:      The solved matrix containing the rotated vector of each linear
%         acceleration component
%

%This assumes that the quaternion is normalised (sqw + sqx + sqy + sqz =1),
%if not it should be normalised before doing the conversion.
%To normalise divide qx, qy, qz and qw by n where n=sqrt(qx2 + qy2 + qz2 + qw2)

 for k = 1:size(q,1)
     rot=[(1-2.*q(k,3).^2-2.*q(k,4).^2) 2.*(q(k,2).*q(k,3)+q(k,1).*q(k,4))...
          2.*(q(k,2).*q(k,4)-q(k,1).*q(k,3));2.*(q(k,2).*q(k,3)-q(k,1).*q(k,4))...
          (1-2.*q(k,2).^2-2.*q(k,4).^2) 2.*(q(k,3).*q(k,4)+q(k,1).*q(k,2));...
         2.*(q(k,2).*q(k,4)+q(k,1).*q(k,3)) 2.*(q(k,3).*q(k,4)-q(k,1).*q(k,2))...
          (1-2.*q(k,2).^2-2.*q(k,3).^2)];
     n(k,:) = rot*r(k,:)';
 end
</code>```

Thanks in advance!

答:
Well first of all, in order for quatrotate to work, you need to use a unit quaternion (i.e. length of 1).

Second of all, I see that you are using the matrix provided by the MATLAB page. I've recently derived that matrix myself and found that the MATLAB page has the wrong matrix.

According to this (page 45), rotating a vector by a quaternion is

p' = p + 2w(v × p)+2(v × (v × p))

Where,

p' is the output vector after rotation,

p is the starting vector to be rotated,

w is the first coefficient in the quaternion,

v is the vector of [second coefficent, third coefficient, fourth coefficient] of the quaternion,

× is the cross product operand.

I encourage you to go to the link and derive the matrix yourself. You will see that the matrix provided on the MATLAB page has the wrong additions and subtractions.

This is what's said on the MATLAB page:

Here's my derivation (here the quaternion is [q0, q1, q2, q3] and the vector is [x, y, z]):

First row:

Second row:

Third row:

Here you can see that the signs are incorrect on MATLAB's website. I've emailed them about the error and is waiting to hear back.

Body:
My version of MATLAB doesn't have the quatrotate function included, so I wrote my own using the equation MathWorks provide here. Trouble is, I don't get the same answers they get in their example in my function, or when I hand calculate it.

Under their example if I input the following I should get an n vector [-1 1 1]:

q = [1 0 1 0]; r = [1 1 1]; n = quatrotate(q, r)

n =

-1.0000    1.0000    1.0000

In my function, and by hand, I get:

[-3 1 1]

What am I missing here? The more I search the more confused I get. As far as I can tell the answer should be [-3 1 1].

Here is the function I wrote:

function [n] = quatrotate(q,r)
%Rotate a given acceleration vector by a given quaternion
%
%Inputs:
% q:      A matrix containing a set of quaternion vectors of the
%         form q = [w,x,y,z]
% r:      A matrix containing a set of linear acceleration vectors
%         of the form r= [i,j,k] (also known as [x,y,z])
%
% Outputs:
% n:      The solved matrix containing the rotated vector of each linear
%         acceleration component
%

%This assumes that the quaternion is normalised (sqw + sqx + sqy + sqz =1),
%if not it should be normalised before doing the conversion.
%To normalise divide qx, qy, qz and qw by n where n=sqrt(qx2 + qy2 + qz2 + qw2)

 for k = 1:size(q,1)
     rot=[(1-2.*q(k,3).^2-2.*q(k,4).^2) 2.*(q(k,2).*q(k,3)+q(k,1).*q(k,4))...
          2.*(q(k,2).*q(k,4)-q(k,1).*q(k,3));2.*(q(k,2).*q(k,3)-q(k,1).*q(k,4))...
          (1-2.*q(k,2).^2-2.*q(k,4).^2) 2.*(q(k,3).*q(k,4)+q(k,1).*q(k,2));...
         2.*(q(k,2).*q(k,4)+q(k,1).*q(k,3)) 2.*(q(k,3).*q(k,4)-q(k,1).*q(k,2))...
          (1-2.*q(k,2).^2-2.*q(k,3).^2)];
     n(k,:) = rot*r(k,:)';
 end

Thanks in advance!


来源: stackexchange

问:
Making GridView Vertically Scrollable
In my ASP.net program, I'm trying to make my gridview have a scrollbar whenever the data doesn't fit in the div. I've looked around and found answers but none of them work, what am I doing wrong? Here's my code, and I've tried changing overflow: scroll to overflow: auto and that hasn't worked either - thanks.

```<code> <div style="width: 100%; height: 200px; overflow:scroll;">
<asp:GridView ID="usersGridView" runat="server" style="z-index: 1; left: 10px; top: 231px; position: absolute; height: 133px; width: 352px" BackColor="White" BorderColor="#336666" BorderStyle="Double" BorderWidth="3px" CellPadding="4" GridLines="Horizontal">
<AlternatingRowStyle BackColor="White" />
<Columns>
    <asp:CommandField ButtonType="Button" HeaderText="Edit" ShowEditButton="True" >
    <ControlStyle BackColor="#336666" ForeColor="White" />
    </asp:CommandField>
</Columns>
<FooterStyle BackColor="White" ForeColor="#333333" />
<HeaderStyle BackColor="#336666" Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="#336666" ForeColor="White" HorizontalAlign="Center" />
<RowStyle BackColor="#d6ded9" ForeColor="#333333" />
<SelectedRowStyle BackColor="#339966" Font-Bold="True" ForeColor="White" />
<SortedAscendingCellStyle BackColor="#F7F7F7" />
<SortedAscendingHeaderStyle BackColor="#487575" />
<SortedDescendingCellStyle BackColor="#E5E5E5" />
<SortedDescendingHeaderStyle BackColor="#275353" />
</asp:GridView>
</div>
</code>```

答:
```<code><div style="width: 100%; height: 200px; overflow-y:scroll;">
</code>```

ContentLicense: CC BY-SA 3.0

Title: Making GridView Vertically Scrollable

Body:
In my ASP.net program, I'm trying to make my gridview have a scrollbar whenever the data doesn't fit in the div. I've looked around and found answers but none of them work, what am I doing wrong? Here's my code, and I've tried changing overflow: scroll to overflow: auto and that hasn't worked either - thanks.

<asp:GridView ID="usersGridView" runat="server" style="z-index: 1; left: 10px; top: 231px; position: absolute; height: 133px; width: 352px" BackColor="White" BorderColor="#336666" BorderStyle="Double" BorderWidth="3px" CellPadding="4" GridLines="Horizontal">
<AlternatingRowStyle BackColor="White" />
<Columns>
    <asp:CommandField ButtonType="Button" HeaderText="Edit" ShowEditButton="True" >
    <ControlStyle BackColor="#336666" ForeColor="White" />
    </asp:CommandField>
</Columns>
<FooterStyle BackColor="White" ForeColor="#333333" />
<HeaderStyle BackColor="#336666" Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="#336666" ForeColor="White" HorizontalAlign="Center" />
<RowStyle BackColor="#d6ded9" ForeColor="#333333" />
<SelectedRowStyle BackColor="#339966" Font-Bold="True" ForeColor="White" />
<SortedAscendingCellStyle BackColor="#F7F7F7" />
<SortedAscendingHeaderStyle BackColor="#487575" />
<SortedDescendingCellStyle BackColor="#E5E5E5" />
<SortedDescendingHeaderStyle BackColor="#275353" />
</asp:GridView>


问:
C++ Storing a string into a class
I made a topic a bit ago regarding structs. And I know that classes have the same concept as structs. How would I go about storing a string into the class?

This is the class

```<code>class studentType
{
public:
    void setData(string, int);
    string getName() const;
    int getId() const;
private:
    string name;
    int sid;
};

void studentType::setData(string, int) {
    name = ??;
    sid = ??;
}

string studentType::getName() const {
    return name;
}

int studentType::getId() const {
    return sid;
}
</code>```

The main consists of:

```<code>int main() {

    studentType object, number;

    cout << "enter name and code of item1: ";
    cin >> object.setData() >> object.setData();
    cout << "enter name and code for item2: ";
    cin >> number.setData() >> number.setData();

    system("pause");
    return 0;
}
</code>```

How would I fix the cin issue? I already have string defined in the header. And yes, I know using namespace std; isn't preferred but it's for simplicity

答:
What you're looking for is std::getline(). I would use cin for getting your integers, but not for the strings. I would separate the user input like this. Like @Suhaib Ahmad said, cin is space-delimited. To get a string including spaces from stdin, use std::getline().

```<code>void studentType::setData(string n, int i) {
    this->name = n;
    this->sid = i;
}
</code>```

-

```<code>int main(void) {
    string n;
    int i;
    studentType object, number;

    cout << "Enter name for item1: ";
    getline(cin, n);
    cout << "Enter code for item1: ";
    cin >> i;

    object = studentType(); // make sure you construct your studentType, I also recommend using a constructor function
    object.setData(n, i);

    cout << "Enter name for item2: ";
    getline(cin, n);
    cout << "Enter code for item2: ";
    cin >> i;
    number = studentType();
    number.setData(n, i);

    system("pause");
    return 0;
}
</code>```

The way you are using setData(), with no arguments given, as a place to store the cin input is incorrect. You would need to declare variables first, and then initialize your class with the variables.

Title: C++ Storing a string into a class

Body:
I made a topic a bit ago regarding structs. And I know that classes have the same concept as structs. How would I go about storing a string into the class?

This is the class

class studentType
{
public:
    void setData(string, int);
    string getName() const;
    int getId() const;
private:
    string name;
    int sid;
};

void studentType::setData(string, int) {
    name = ??;
    sid = ??;
}

string studentType::getName() const {
    return name;
}

int studentType::getId() const {
    return sid;
}

The main consists of:

int main() {

    studentType object, number;

    cout << "enter name and code of item1: ";
    cin >> object.setData() >> object.setData();
    cout << "enter name and code for item2: ";
    cin >> number.setData() >> number.setData();

    system("pause");
    return 0;
}

How would I fix the cin issue? I already have string defined in the header. And yes, I know using namespace std; isn't preferred but it's for simplicity

Body:
What you're looking for is std::getline(). I would use cin for getting your integers, but not for the strings. I would separate the user input like this. Like @Suhaib Ahmad said, cin is space-delimited. To get a string including spaces from stdin, use std::getline().

void studentType::setData(string n, int i) {
    this->name = n;
    this->sid = i;
}

-

int main(void) {
    string n;
    int i;
    studentType object, number;

    cout << "Enter name for item1: ";
    getline(cin, n);
    cout << "Enter code for item1: ";
    cin >> i;

    object = studentType(); // make sure you construct your studentType, I also recommend using a constructor function
    object.setData(n, i);

    cout << "Enter name for item2: ";
    getline(cin, n);
    cout << "Enter code for item2: ";
    cin >> i;
    number = studentType();
    number.setData(n, i);

    system("pause");
    return 0;
}

The way you are using setData(), with no arguments given, as a place to store the cin input is incorrect. You would need to declare variables first, and then initialize your class with the variables.


问:
TypeScript, how to pass public field names with typed expression
I'm trying to figure out how to pass an array of propertynames (or fieldnames) of a given object, without using so called magic strings - because typos are easily made! In essence, I'm looking for something relevant to csharp's "Expression<>" I think.

E.g. with magic strings:
searchFilter(model, 'searchParameter', ['id', 'name'])

E.g. typed, or how I would like to call the function:
searchFilter(model, 'searchParameter', [m => m.id, m => m.name])

As a reference, this function looks a bit like this:

with magic strings: (or how I was trying to do it typed)

```<code>private searchFilter(mode: Model, q: string, properties: string[]): boolean {
   if (q === '') return true;

   q = q.trim().toLowerCase();

   for (let property of properties) {
     if (vacature[property.toString()].toString().toLowerCase().indexOf(q) >= 0) {
       return true;
     }
  }

  return false;
}
</code>```

typed: (or how I was trying to do it typed, but this ofcourse just gives back functions.. I'd need a relevant 'function expression' as in C# to extract the called property, to get it's name)

```<code>private searchFilter(mode: Model, q: string, propertySelector: ((x: Model) => any | string)[]): boolean {
   if (q === '') return true;

   q = q.trim().toLowerCase();

   for (let property of propertySelector) {
     if (vacature[property.toString()].toString().toLowerCase().indexOf(q) >= 0) {
       return true;
     }
  }

  return false;
 }
</code>```

答:
It's possible to create closure methods with the same names as properties and call required one:

```<code>class Foo {
    public bar: string = null; // property has to be initialized
}

function getPropertyName<T>(TCreator: { new(): T; }, expression: Function): string {
    let obj = new TCreator();
    Object.keys(obj).map(k => { obj[k] = () => k; });
    return expression(obj)();
}

let result = getPropertyName(Foo, (o: Foo) => o.bar);
console.log(result); // Output: `bar`
</code>```

The same approach but objects instead of classes is here

Body:
I'm trying to figure out how to pass an array of propertynames (or fieldnames) of a given object, without using so called magic strings - because typos are easily made! In essence, I'm looking for something relevant to csharp's "Expression<>" I think.

E.g. with magic strings:
searchFilter(model, 'searchParameter', ['id', 'name'])

E.g. typed, or how I would like to call the function:
searchFilter(model, 'searchParameter', [m => m.id, m => m.name])

As a reference, this function looks a bit like this:

with magic strings: (or how I was trying to do it typed)

private searchFilter(mode: Model, q: string, properties: string[]): boolean {
   if (q === '') return true;

   q = q.trim().toLowerCase();

   for (let property of properties) {
     if (vacature[property.toString()].toString().toLowerCase().indexOf(q) >= 0) {
       return true;
     }
  }

  return false;
}

typed: (or how I was trying to do it typed, but this ofcourse just gives back functions.. I'd need a relevant 'function expression' as in C# to extract the called property, to get it's name)

private searchFilter(mode: Model, q: string, propertySelector: ((x: Model) => any | string)[]): boolean {
   if (q === '') return true;

   q = q.trim().toLowerCase();

   for (let property of propertySelector) {
     if (vacature[property.toString()].toString().toLowerCase().indexOf(q) >= 0) {
       return true;
     }
  }

  return false;
 }

Body:
It's possible to create closure methods with the same names as properties and call required one:

class Foo {
    public bar: string = null; // property has to be initialized
}

function getPropertyName<T>(TCreator: { new(): T; }, expression: Function): string {
    let obj = new TCreator();
    Object.keys(obj).map(k => { obj[k] = () => k; });
    return expression(obj)();
}

let result = getPropertyName(Foo, (o: Foo) => o.bar);
console.log(result); // Output: `bar`

The same approach but objects instead of classes is here


问:
YouTube video muted when scroll down or sticky and still play

How to create a YouTube video when on the header sounded and muted when not display or sticky scroll down?

```<code>function onYouTubeIframeAPIReady() {

  $('iframe[src*="youtube"]').each(function(i) {
    var youtubeIframeId = $(this).attr('id');
    if (!youtubeIframeId) {
      youtubeIframeId = $(this).attr('src').split('?')[0].split('/').pop();
      $(this).attr('id', youtubeIframeId);
    }

    var $video = $("#" + youtubeIframeId),
      videoData = $video.data(),
      videoId = videoData.videoId;

    /**
     * Remove videoId property from data
     */

    //delete videoData.videoId;

    /* jshint camelcase:false */

    if ($(this).attr('src').indexOf('enablejsapi=1') > 0) {
      var player = new YT.Player(youtubeIframeId, {
        videoId: youtubeIframeId, // YouTube Video ID
        //videoId   : $video.data( "videoId" ), // YouTube Video ID
        // width        : "100%",                   // Player width (in px)
        // height       : "auto",                   // Player height (in px)
        playerVars: $.extend({
          autoplay: 1, // Auto-play the video on load
          controls: 1, // Show pause/play buttons in player
          showinfo: 0, // Hide the video title
          modestbranding: 1, // Hide the Youtube Logo
          loop: 1, // Run the video in a loop
          fs: 0, // Hide the full screen button
          cc_load_policy: 0, // Hide closed captions
          iv_load_policy: 3, // Hide the Video Annotations
          autohide: 0 // Hide video controls when playing
        }),

        // }, videoData ),
        events: {
          // onReady: function(e) {
          //   e.target.mute();
          // }
          onStateChange: onPlayerStateChange
        }
      });
    } else {

      $(this).attr('src', $(this).attr('src') + '&enablejsapi=1').on('load', function() {
        var player = new YT.Player(youtubeIframeId, {
          videoId: youtubeIframeId, // YouTube Video ID
          // videoId    : $video.data( "videoId" ), // YouTube Video ID
          // width      : "100%",                   // Player width (in px)
          // height         : "auto",                   // Player height (in px)
          playerVars: $.extend({
            autoplay: 1, // Auto-play the video on load
            controls: 1, // Show pause/play buttons in player
            showinfo: 0, // Hide the video title
            modestbranding: 1, // Hide the Youtube Logo
            loop: 1, // Run the video in a loop
            fs: 0, // Hide the full screen button
            cc_load_policy: 0, // Hide closed captions
            iv_load_policy: 3, // Hide the Video Annotations
            autohide: 0 // Hide video controls when playing
          }),

          // }, videoData ),
          events: {
            // onReady : function(e)
            // {
            //  var $video = $(e.target.a);
            //  if( $video.data( "mute" ) ) e.target.mute();
            //  else e.target.unMute();
            // },
            onStateChange: onPlayerStateChange
          }
        });
      });
    }
  });
  /* jshint camelcase:true */
}
</code>```

This is my sticky video on scroll

```<code>/**
 * FUNCTION STICKY YOUTUBE VIDEO ON SCROLL
 */

var $window = $(window),
  $stickyVideoContainer = $("#stickyvideo_container"),
  $btnHideStickyVideo = $("#hide_sticky_video"),
  $stickyVideo = $("#sticky_video"),
  $headerStickyVideo = $("#header_sticky_video");

function onPlayerStateChange(event) {
  var isPlay = 1 === event.data,
    isPause = 2 === event.data,
    isEnd = 0 === event.data;

  if (isPlay) {
    $stickyVideo.removeClass("is-paused");
    $stickyVideo.toggleClass("is-playing");
  }

  if (isPause) {
    $stickyVideo.removeClass("is-playing");
    $stickyVideo.toggleClass("is-paused");
  }

  if (isEnd) {
    $stickyVideo.removeClass("is-playing", "is-paused");
  }
}

function scrollVideoSticky($window, $stickyVideoContainer, $stickyVideo) {

  // var done = false;

  if ($stickyVideoContainer.length) {
    var containerTop = $stickyVideoContainer.offset().top,
      containerOffset = Math.floor(containerTop + ($stickyVideoContainer.outerHeight() / 2));

  }

  $window.on("resize", function() {
    if ($stickyVideoContainer.length) {
      containerTop = $stickyVideoContainer.offset().top,
        containerOffset = Math.floor(containerTop + ($stickyVideoContainer.outerHeight() / 2));
    }

  }).on("scroll", function() {

    if ($stickyVideo.hasClass('is-hide') && $btnHideStickyVideo.hasClass('is-hide') && $headerStickyVideo.hasClass('is-hide')) {
      if ($window.scrollTop() < containerOffset) {
        $btnHideStickyVideo.hide();
      } else {
        $btnHideStickyVideo.show();
      }

    } else {

      $stickyVideo.toggleClass("is-sticky", //&& $stickyVideo.hasClass( "is-playing" )
        $window.scrollTop() > containerOffset
      ).removeClass('is-show');

      $btnHideStickyVideo.toggleClass("is-sticky",
        $window.scrollTop() > containerOffset
      ).removeClass('is-show');

      $headerStickyVideo.toggleClass("is-sticky",
        $window.scrollTop() > containerOffset
      ).removeClass('is-show');
    }

  });
}
</code>```

I want video on header is sounded and when scroll down the video is muted and still play, and when back scroll up to header, the video back sounded.

I already put the code

```<code>events: {
           onReady: function(e) {
             e.target.mute();
           }
</code>```

in onYouTubeIframeAPIReady(), the video is muted both, and when I put that code in function scrollVideoSticky(), the sticky is gone. Where should I put that code?

Please help or share your idea will be highly appreciate. Thanks!

答:
I came up with a script to handle the N number of videos from YT videos and Videos from Video Tag.If the Video is playing and its not in the view-port, it will be getting sticky.You can Refer my code pen out here

Ref:https://codepen.io/aravi-pen/pen/VMaRvX

Here is JS

```<code>var ytIframeList, videoList, currentPlayer, closeButton, gradientOverlay, fullScreenIcon;

var inViewPortBol = true;

var ytIframeIdList = [];

var ytVideoId = [];

var ytPlayerId = [];

var videoTagId = [];

var events = new Array("ended", "pause", "playing");

document.addEventListener('DOMContentLoaded', function () {

    /*Adding Youtube Iframe API to body*/

    var youTubeVideoTag = document.createElement('script');

    youTubeVideoTag.src = "//www.youtube.com/iframe_api";

    var firstScriptTag = document.getElementsByTagName('script')[0];

    document.body.appendChild(youTubeVideoTag, firstScriptTag);

    /*Getting all the iframe from the Page and finding out valid URL and ID. Then creating instance of players*/

    ytIframeList = document.getElementsByTagName("iframe");

    for (i = 0; i < ytIframeList.length; i++) {

        if (new RegExp("\\b" + "enablejsapi" + "\\b").test(ytIframeList[i].src)) {

            var url = ytIframeList[i].src.replace(/(>|<)/gi, '').split(/(vi\/|v=|\/v\/|youtu\.be\/|\/embed\/)/);

            if (url[2] !== undefined) {

                ID = url[2].split(/[^0-9a-z_\-]/i);

                ID = ID[0];

                ytIframeIdList.push(ID);

                ytIframeList[i].id = "featured-video" + i;

                ytVideoId.push("ytVideoId" + i);

                ytVideoId[i] = document.getElementById(ytIframeList[i].id);

                ytPlayerId.push("player" + i);

            }

        }

    }

    /*Getting Video Tag List and Creating instances*/

    videoList = document.getElementsByTagName("video");

    for (i = 0; i < videoList.length; i++) {

        videoList[i].id = "video-featured" + i;

        videoTagId.push("videoPlayerId" + i);

        videoTagId[i] = document.getElementById(videoList[i].id);

    }

    for (i = 0; i < videoTagId.length; i++) {

        for (var j in events) {

            videoTagId[i].addEventListener(events[j], videoTagPlayerhandler, false);

        }

    }

    closeButton = document.querySelector("a.close-button");

    gradientOverlay = document.querySelector(".gradient-overlay");

    fullScreenIcon = document.querySelector("i.fa.fa-arrows-alt");

    fullScreenPlay();

});

window.onYouTubeIframeAPIReady = function () {

    for (i = 0; i < ytIframeIdList.length; i++) {

        ytPlayerId[i] = new YT.Player(ytIframeList[i].id, {

            events: {

                "onStateChange": onPlayerStateChange

            }

        });

    }

};

function videoTagPlayerhandler(e) {

    /*Play Rules*/

    for (i = 0; i < videoTagId.length; i++) {

        if (e.target == videoTagId[i]) {

            if (e.type == "playing") {

                currentPlayer = videoTagId[i];

                videoTagId[i].classList.remove("is-paused");

                videoTagId[i].classList.add("is-playing");

                break;

            }

        }

    }

    for (i = 0; i < videoTagId.length; i++) {

        if (currentPlayer == videoTagId[i]) {

            continue;

        }

        videoTagId[i].classList.remove("is-playing");

        videoTagId[i].classList.add("is-paused");

    }

    /*Pause Rules*/

    for (i = 0; i < videoTagId.length; i++) {

        if (e.target == videoTagId[i]) {

            if (e.type == "pause") {

                videoTagId[i].classList.add("is-paused");

                videoTagId[i].classList.remove("is-playing");

                videoTagId[i].pause();

            }

        }

    }

    /*Sticky Rules*/

    for (i = 0; i < videoTagId.length; i++) {

        if (videoTagId[i].classList.contains("is-sticky")) {

            videoTagId[i].pause();

            fullScreenIcon.style.display = "none";

        }

    }

    for (i = 0; i < ytPlayerId.length; i++) {

        if (ytVideoId[i].classList.contains("is-sticky")) {

            ytPlayerId[i].pauseVideo();

            fullScreenIcon.style.display = "none";

        }

    }

    /*End Rules*/

    for (i = 0; i < videoTagId.length; i++) {

        if (e.target == videoTagId[i]) {

            if (e.type == "ended") {

                videoTagId[i].classList.remove("is-playing");

                videoTagId[i].classList.remove("is-paused");

            }

        }

    }

    videohandler();

};

function onPlayerStateChange(event) {

    /*Play Rules*/

    for (i = 0; i < ytPlayerId.length; i++) {

        if (ytPlayerId[i].getPlayerState() === 1) {

            currentPlayer = ytVideoId[i];

            ytVideoId[i].classList.remove("is-paused");

            ytVideoId[i].classList.add("is-playing");

            break;

        }

    }

    for (i = 0; i < ytVideoId.length; i++) {

        if (currentPlayer == ytVideoId[i]) {

            continue;

        }

        ytVideoId[i].classList.remove("is-playing");

        ytVideoId[i].classList.add("is-paused");

    }

    /*Pause Rules*/

    for (i = 0; i < ytPlayerId.length; i++) {

        if (ytPlayerId[i].getPlayerState() === 2) {

            ytVideoId[i].classList.add("is-paused");

            ytVideoId[i].classList.remove("is-playing");

            ytPlayerId[i].pauseVideo();

        }

    }

    /*Sticky Rules*/

    for (i = 0; i < ytPlayerId.length; i++) {

        if (ytVideoId[i].classList.contains("is-sticky")) {

            ytPlayerId[i].pauseVideo();

            fullScreenIcon.style.display = "none";

        }

    }

    for (i = 0; i < videoTagId.length; i++) {

        if (videoTagId[i].classList.contains("is-sticky")) {

            videoTagId[i].pause();

            fullScreenIcon.style.display = "none";

        }

    }

    /*End Rule*/

    for (i = 0; i < ytPlayerId.length; i++) {

        if (ytPlayerId[i].getPlayerState() === 0) {

            ytVideoId[i].classList.remove("is-playing");

            ytVideoId[i].classList.remove("is-paused");

        }

    }

    videohandler();

}

function videohandler() {

    if (currentPlayer) {

        if (closeButton) {

            closeButton.addEventListener("click", function (e) {

                if (currentPlayer.classList.contains("is-sticky")) {

                    currentPlayer.classList.remove("is-sticky");

                    closeFloatVideo();

                    for (i = 0; i < ytVideoId.length; i++) {

                        if (currentPlayer == ytVideoId[i]) {

                            ytPlayerId[i].pauseVideo();

                        }

                    }

                    for (i = 0; i < videoTagId.length; i++) {

                        if (currentPlayer == videoTagId[i]) {

                            videoTagId[i].pause();

                        }

                    }

                } else {

                    for (i = 0; i < ytVideoId.length; i++) {

                        if (currentPlayer != ytVideoId[i]) {

                            ytVideoId[i].classList.remove("is-sticky");

                            closeFloatVideo();

                        }

                    }

                    for (i = 0; i < videoTagId.length; i++) {

                        if (currentPlayer != videoTagId[i]) {

                            videoTagId[i].classList.remove("is-sticky");

                            closeFloatVideo();

                        }

                    }

                }

            });

        }

    }

}

window.addEventListener('scroll', function () {

    inViewPortBol = inViewPort();

    if (currentPlayer) {

        if (!inViewPortBol && currentPlayer.classList.contains("is-playing")) {

            for (i = 0; i < ytVideoId.length; i++) {

                if (currentPlayer != ytVideoId[i]) {

                    ytVideoId[i].classList.remove("is-sticky");

                }

            }

            for (i = 0; i < videoTagId.length; i++) {

                if (currentPlayer != videoTagId[i]) {

                    videoTagId[i].classList.remove("is-sticky");

                }

            }

            currentPlayer.classList.add("is-sticky");

            openFloatVideo();

        } else {

            if (currentPlayer.classList.contains("is-sticky")) {

                currentPlayer.classList.remove("is-sticky");

                closeFloatVideo();

            }

        }

    }

});

function fullScreenPlay() {

    if (fullScreenIcon) {

        fullScreenIcon.addEventListener("click", function () {

            if (currentPlayer.requestFullscreen) {

                currentPlayer.requestFullscreen();

            } else if (currentPlayer.msRequestFullscreen) {

                currentPlayer.msRequestFullscreen();

            } else if (currentPlayer.mozRequestFullScreen) {

                currentPlayer.mozRequestFullScreen();

            } else if (currentPlayer.webkitRequestFullscreen) {

                currentPlayer.webkitRequestFullscreen();

            }

        });

    }

}

function inViewPort() {

    if (currentPlayer) {

        var videoParentLocal = currentPlayer.parentElement.getBoundingClientRect();

        return videoParentLocal.bottom > 0 &&

            videoParentLocal.right > 0 &&

            videoParentLocal.left < (window.innerWidth || document.documentElement.clientWidth) &&

            videoParentLocal.top < (window.innerHeight || document.documentElement.clientHeight);

    }

}

function openFloatVideo() {

    closeButton.style.display = "block";

    gradientOverlay.style.display = "block";

    fullScreenIcon.style.display = "block";

}

function closeFloatVideo() {

    closeButton.style.display = "none";

    gradientOverlay.style.display = "none";

    fullScreenIcon.style.display = "none";

}
</code>```

Check for CSS and HTML requirements in codepen.
Thanks !

Body:
How to create a YouTube video when on the header sounded and muted when not display or sticky scroll down?

function onYouTubeIframeAPIReady() {

  $('iframe[src*="youtube"]').each(function(i) {
    var youtubeIframeId = $(this).attr('id');
    if (!youtubeIframeId) {
      youtubeIframeId = $(this).attr('src').split('?')[0].split('/').pop();
      $(this).attr('id', youtubeIframeId);
    }

    var $video = $("#" + youtubeIframeId),
      videoData = $video.data(),
      videoId = videoData.videoId;

    /**
     * Remove videoId property from data
     */

    //delete videoData.videoId;

    /* jshint camelcase:false */

    if ($(this).attr('src').indexOf('enablejsapi=1') > 0) {
      var player = new YT.Player(youtubeIframeId, {
        videoId: youtubeIframeId, // YouTube Video ID
        //videoId   : $video.data( "videoId" ), // YouTube Video ID
        // width        : "100%",                   // Player width (in px)
        // height       : "auto",                   // Player height (in px)
        playerVars: $.extend({
          autoplay: 1, // Auto-play the video on load
          controls: 1, // Show pause/play buttons in player
          showinfo: 0, // Hide the video title
          modestbranding: 1, // Hide the Youtube Logo
          loop: 1, // Run the video in a loop
          fs: 0, // Hide the full screen button
          cc_load_policy: 0, // Hide closed captions
          iv_load_policy: 3, // Hide the Video Annotations
          autohide: 0 // Hide video controls when playing
        }),

        // }, videoData ),
        events: {
          // onReady: function(e) {
          //   e.target.mute();
          // }
          onStateChange: onPlayerStateChange
        }
      });
    } else {

      $(this).attr('src', $(this).attr('src') + '&enablejsapi=1').on('load', function() {
        var player = new YT.Player(youtubeIframeId, {
          videoId: youtubeIframeId, // YouTube Video ID
          // videoId    : $video.data( "videoId" ), // YouTube Video ID
          // width      : "100%",                   // Player width (in px)
          // height         : "auto",                   // Player height (in px)
          playerVars: $.extend({
            autoplay: 1, // Auto-play the video on load
            controls: 1, // Show pause/play buttons in player
            showinfo: 0, // Hide the video title
            modestbranding: 1, // Hide the Youtube Logo
            loop: 1, // Run the video in a loop
            fs: 0, // Hide the full screen button
            cc_load_policy: 0, // Hide closed captions
            iv_load_policy: 3, // Hide the Video Annotations
            autohide: 0 // Hide video controls when playing
          }),

          // }, videoData ),
          events: {
            // onReady : function(e)
            // {
            //  var $video = $(e.target.a);
            //  if( $video.data( "mute" ) ) e.target.mute();
            //  else e.target.unMute();
            // },
            onStateChange: onPlayerStateChange
          }
        });
      });
    }
  });
  /* jshint camelcase:true */
}

This is my sticky video on scroll

/**
 * FUNCTION STICKY YOUTUBE VIDEO ON SCROLL
 */

var $window = $(window),
  $stickyVideoContainer = $("#stickyvideo_container"),
  $btnHideStickyVideo = $("#hide_sticky_video"),
  $stickyVideo = $("#sticky_video"),
  $headerStickyVideo = $("#header_sticky_video");

function onPlayerStateChange(event) {
  var isPlay = 1 === event.data,
    isPause = 2 === event.data,
    isEnd = 0 === event.data;

  if (isPlay) {
    $stickyVideo.removeClass("is-paused");
    $stickyVideo.toggleClass("is-playing");
  }

  if (isPause) {
    $stickyVideo.removeClass("is-playing");
    $stickyVideo.toggleClass("is-paused");
  }

  if (isEnd) {
    $stickyVideo.removeClass("is-playing", "is-paused");
  }
}

function scrollVideoSticky($window, $stickyVideoContainer, $stickyVideo) {

  // var done = false;

  if ($stickyVideoContainer.length) {
    var containerTop = $stickyVideoContainer.offset().top,
      containerOffset = Math.floor(containerTop + ($stickyVideoContainer.outerHeight() / 2));

  }

  $window.on("resize", function() {
    if ($stickyVideoContainer.length) {
      containerTop = $stickyVideoContainer.offset().top,
        containerOffset = Math.floor(containerTop + ($stickyVideoContainer.outerHeight() / 2));
    }

  }).on("scroll", function() {

    if ($stickyVideo.hasClass('is-hide') && $btnHideStickyVideo.hasClass('is-hide') && $headerStickyVideo.hasClass('is-hide')) {
      if ($window.scrollTop() < containerOffset) {
        $btnHideStickyVideo.hide();
      } else {
        $btnHideStickyVideo.show();
      }

    } else {

      $stickyVideo.toggleClass("is-sticky", //&& $stickyVideo.hasClass( "is-playing" )
        $window.scrollTop() > containerOffset
      ).removeClass('is-show');

      $btnHideStickyVideo.toggleClass("is-sticky",
        $window.scrollTop() > containerOffset
      ).removeClass('is-show');

      $headerStickyVideo.toggleClass("is-sticky",
        $window.scrollTop() > containerOffset
      ).removeClass('is-show');
    }

  });
}

I want video on header is sounded and when scroll down the video is muted and still play, and when back scroll up to header, the video back sounded.

I already put the code

events: {
           onReady: function(e) {
             e.target.mute();
           }

in onYouTubeIframeAPIReady(), the video is muted both, and when I put that code in function scrollVideoSticky(), the sticky is gone. Where should I put that code?

Please help or share your idea will be highly appreciate. Thanks!

Body:
I came up with a script to handle the N number of videos from YT videos and Videos from Video Tag.If the Video is playing and its not in the view-port, it will be getting sticky.You can Refer my code pen out here

Ref:https://codepen.io/aravi-pen/pen/VMaRvX

Here is JS

var ytIframeList, videoList, currentPlayer, closeButton, gradientOverlay, fullScreenIcon;

var inViewPortBol = true;

var ytIframeIdList = [];

var ytVideoId = [];

var ytPlayerId = [];

var videoTagId = [];

var events = new Array("ended", "pause", "playing");

document.addEventListener('DOMContentLoaded', function () {

    /*Adding Youtube Iframe API to body*/

    var youTubeVideoTag = document.createElement('script');

    youTubeVideoTag.src = "//www.youtube.com/iframe_api";

    var firstScriptTag = document.getElementsByTagName('script')[0];

    document.body.appendChild(youTubeVideoTag, firstScriptTag);

    /*Getting all the iframe from the Page and finding out valid URL and ID. Then creating instance of players*/

    ytIframeList = document.getElementsByTagName("iframe");

    for (i = 0; i < ytIframeList.length; i++) {

        if (new RegExp("\\b" + "enablejsapi" + "\\b").test(ytIframeList[i].src)) {

            var url = ytIframeList[i].src.replace(/(>|<)/gi, '').split(/(vi\/|v=|\/v\/|youtu\.be\/|\/embed\/)/);

            if (url[2] !== undefined) {

                ID = url[2].split(/[^0-9a-z_\-]/i);

                ID = ID[0];

                ytIframeIdList.push(ID);

                ytIframeList[i].id = "featured-video" + i;

                ytVideoId.push("ytVideoId" + i);

                ytVideoId[i] = document.getElementById(ytIframeList[i].id);

                ytPlayerId.push("player" + i);

            }

        }

    }

    /*Getting Video Tag List and Creating instances*/

    videoList = document.getElementsByTagName("video");

    for (i = 0; i < videoList.length; i++) {

        videoList[i].id = "video-featured" + i;

        videoTagId.push("videoPlayerId" + i);

        videoTagId[i] = document.getElementById(videoList[i].id);

    }

    for (i = 0; i < videoTagId.length; i++) {

        for (var j in events) {

            videoTagId[i].addEventListener(events[j], videoTagPlayerhandler, false);

        }

    }

    closeButton = document.querySelector("a.close-button");

    gradientOverlay = document.querySelector(".gradient-overlay");

    fullScreenIcon = document.querySelector("i.fa.fa-arrows-alt");

    fullScreenPlay();

});

window.onYouTubeIframeAPIReady = function () {

    for (i = 0; i < ytIframeIdList.length; i++) {

        ytPlayerId[i] = new YT.Player(ytIframeList[i].id, {

            events: {

                "onStateChange": onPlayerStateChange

            }

        });

    }

};

function videoTagPlayerhandler(e) {

    /*Play Rules*/

    for (i = 0; i < videoTagId.length; i++) {

        if (e.target == videoTagId[i]) {

            if (e.type == "playing") {

                currentPlayer = videoTagId[i];

                videoTagId[i].classList.remove("is-paused");

                videoTagId[i].classList.add("is-playing");

                break;

            }

        }

    }

    for (i = 0; i < videoTagId.length; i++) {

        if (currentPlayer == videoTagId[i]) {

            continue;

        }

        videoTagId[i].classList.remove("is-playing");

        videoTagId[i].classList.add("is-paused");

    }

    /*Pause Rules*/

    for (i = 0; i < videoTagId.length; i++) {

        if (e.target == videoTagId[i]) {

            if (e.type == "pause") {

                videoTagId[i].classList.add("is-paused");

                videoTagId[i].classList.remove("is-playing");

                videoTagId[i].pause();

            }

        }

    }

    /*Sticky Rules*/

    for (i = 0; i < videoTagId.length; i++) {

        if (videoTagId[i].classList.contains("is-sticky")) {

            videoTagId[i].pause();

            fullScreenIcon.style.display = "none";

        }

    }

    for (i = 0; i < ytPlayerId.length; i++) {

        if (ytVideoId[i].classList.contains("is-sticky")) {

            ytPlayerId[i].pauseVideo();

            fullScreenIcon.style.display = "none";

        }

    }

    /*End Rules*/

    for (i = 0; i < videoTagId.length; i++) {

        if (e.target == videoTagId[i]) {

            if (e.type == "ended") {

                videoTagId[i].classList.remove("is-playing");

                videoTagId[i].classList.remove("is-paused");

            }

        }

    }

    videohandler();

};

function onPlayerStateChange(event) {

    /*Play Rules*/

    for (i = 0; i < ytPlayerId.length; i++) {

        if (ytPlayerId[i].getPlayerState() === 1) {

            currentPlayer = ytVideoId[i];

            ytVideoId[i].classList.remove("is-paused");

            ytVideoId[i].classList.add("is-playing");

            break;

        }

    }

    for (i = 0; i < ytVideoId.length; i++) {

        if (currentPlayer == ytVideoId[i]) {

            continue;

        }

        ytVideoId[i].classList.remove("is-playing");

        ytVideoId[i].classList.add("is-paused");

    }

    /*Pause Rules*/

    for (i = 0; i < ytPlayerId.length; i++) {

        if (ytPlayerId[i].getPlayerState() === 2) {

            ytVideoId[i].classList.add("is-paused");

            ytVideoId[i].classList.remove("is-playing");

            ytPlayerId[i].pauseVideo();

        }

    }

    /*Sticky Rules*/

    for (i = 0; i < ytPlayerId.length; i++) {

        if (ytVideoId[i].classList.contains("is-sticky")) {

            ytPlayerId[i].pauseVideo();

            fullScreenIcon.style.display = "none";

        }

    }

    for (i = 0; i < videoTagId.length; i++) {

        if (videoTagId[i].classList.contains("is-sticky")) {

            videoTagId[i].pause();

            fullScreenIcon.style.display = "none";

        }

    }

    /*End Rule*/

    for (i = 0; i < ytPlayerId.length; i++) {

        if (ytPlayerId[i].getPlayerState() === 0) {

            ytVideoId[i].classList.remove("is-playing");

            ytVideoId[i].classList.remove("is-paused");

        }

    }

    videohandler();

}

function videohandler() {

    if (currentPlayer) {

        if (closeButton) {

            closeButton.addEventListener("click", function (e) {

                if (currentPlayer.classList.contains("is-sticky")) {

                    currentPlayer.classList.remove("is-sticky");

                    closeFloatVideo();

                    for (i = 0; i < ytVideoId.length; i++) {

                        if (currentPlayer == ytVideoId[i]) {

                            ytPlayerId[i].pauseVideo();

                        }

                    }

                    for (i = 0; i < videoTagId.length; i++) {

                        if (currentPlayer == videoTagId[i]) {

                            videoTagId[i].pause();

                        }

                    }

                } else {

                    for (i = 0; i < ytVideoId.length; i++) {

                        if (currentPlayer != ytVideoId[i]) {

                            ytVideoId[i].classList.remove("is-sticky");

                            closeFloatVideo();

                        }

                    }

                    for (i = 0; i < videoTagId.length; i++) {

                        if (currentPlayer != videoTagId[i]) {

                            videoTagId[i].classList.remove("is-sticky");

                            closeFloatVideo();

                        }

                    }

                }

            });

        }

    }

}

window.addEventListener('scroll', function () {

    inViewPortBol = inViewPort();

    if (currentPlayer) {

        if (!inViewPortBol && currentPlayer.classList.contains("is-playing")) {

            for (i = 0; i < ytVideoId.length; i++) {

                if (currentPlayer != ytVideoId[i]) {

                    ytVideoId[i].classList.remove("is-sticky");

                }

            }

            for (i = 0; i < videoTagId.length; i++) {

                if (currentPlayer != videoTagId[i]) {

                    videoTagId[i].classList.remove("is-sticky");

                }

            }

            currentPlayer.classList.add("is-sticky");

            openFloatVideo();

        } else {

            if (currentPlayer.classList.contains("is-sticky")) {

                currentPlayer.classList.remove("is-sticky");

                closeFloatVideo();

            }

        }

    }

});

function fullScreenPlay() {

    if (fullScreenIcon) {

        fullScreenIcon.addEventListener("click", function () {

            if (currentPlayer.requestFullscreen) {

                currentPlayer.requestFullscreen();

            } else if (currentPlayer.msRequestFullscreen) {

                currentPlayer.msRequestFullscreen();

            } else if (currentPlayer.mozRequestFullScreen) {

                currentPlayer.mozRequestFullScreen();

            } else if (currentPlayer.webkitRequestFullscreen) {

                currentPlayer.webkitRequestFullscreen();

            }

        });

    }

}

function inViewPort() {

    if (currentPlayer) {

        var videoParentLocal = currentPlayer.parentElement.getBoundingClientRect();

        return videoParentLocal.bottom > 0 &&

            videoParentLocal.right > 0 &&

            videoParentLocal.left < (window.innerWidth || document.documentElement.clientWidth) &&

            videoParentLocal.top < (window.innerHeight || document.documentElement.clientHeight);

    }

}

function openFloatVideo() {

    closeButton.style.display = "block";

    gradientOverlay.style.display = "block";

    fullScreenIcon.style.display = "block";

}

function closeFloatVideo() {

    closeButton.style.display = "none";

    gradientOverlay.style.display = "none";

    fullScreenIcon.style.display = "none";

}

Check for CSS and HTML requirements in codepen.
Thanks !


问:
DirectWrite GDI interop: Simple way to draw text using an `IDWriteFontFace`
I have a device context which has some font selected into it, and I would like to DrawText on an ID2D1RenderTarget.

Currently, I go the following route to acchieve this:

Obtain an IDWriteFontFace via CreateFontFaceFromHdc.

Obtain an IDWriteFont from the IDWriteFontFace via the default system font collection (which I get via GetSystemFontCollection - see the next step).

Obtain an IDWriteTextFormat via CreateTextFormat, supplying the parameters specified in the IDWriteFont and specifying nullptr as fontCollection, indicating that I would like to use the default system font collection.

Pass the IDWriteTextFormat to DrawText.

What I find strange about this is that I already have an IDWriteFontFace in the first step, and apparently have to "go back" and ask a font collection for an IDWriteFont, just to pass that to a DrawTextFormat, which can then be used to DrawText. This seems unnecessarily complicated - especially since to draw the text, the system probably has to go down to a IDWriteFontFace anyway, right?

I found DrawGlyphRun, but this takes e.g. a baselineOrigin, which I would have to compute beforehand (not to mention the glyphRun itself).

Isn't there a simpler way to draw text onto an ID2D1RenderTarget if I already have an IDWriteFontFace?

答: That's the only way, like you described. You go back to construct text format instance, and then use it for DirectWrite-style rendering. DrawGlyphRun is a low level method, you can use it of course, but you'll have to implement a lot of layout logic yourself, and that's something to avoid. Generally speaking DrawText is the least efficient method of rendering with Direct2D, better way is to create layout object once and use it every time you need to redraw.


问:
How to add design dependency in android studio 3.0. its not working in standard way
```<code>apply plugin: 'com.android.application'

android {
    compileSdkVersion 26
    defaultConfig {
        applicationId "com.example.rohit.ironman"
        minSdkVersion 15
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner"android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.android.support:appcompat-v7:26.0.0-beta1'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:0.5'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
    compile 'com.android.support:design:26.1.1'
}
</code>```

I have also tried-

Implementation 'com.android.support:design:26.1.1'
instead of

compile 'com.android.support:design:26.1.1'
but still the gradle sync fails

my gradle version is 4.1

android plugin version is 3.0.1

答:
Try to add the missing code from here

```<code>    buildscript {
        repositories {
            jcenter()
            google()
        }
        dependencies {
            classpath 'com.android.tools.build:gradle:3.0.1'
            classpath 'com.google.gms:google-services:3.0.0'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
    }

allprojects {
    repositories {
        jcenter()
        mavenCentral()
        maven {
            url "https://jitpack.io"
        }
        google()
    }
}
</code>```

and add this to your build.gradle(Module:app)

```<code>dependencies {
    compile 'com.android.support:appcompat-v7:27.0.1'
    compile 'com.android.support:design:27.0.1'
    compile 'com.android.support:support-v4:27.0.1'
    }
</code>```

Body:
apply plugin: 'com.android.application'

android {
    compileSdkVersion 26
    defaultConfig {
        applicationId "com.example.rohit.ironman"
        minSdkVersion 15
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner"android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.android.support:appcompat-v7:26.0.0-beta1'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:0.5'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
    compile 'com.android.support:design:26.1.1'
}

I have also tried-

Implementation 'com.android.support:design:26.1.1'
instead of

compile 'com.android.support:design:26.1.1'
but still the gradle sync fails

my gradle version is 4.1

android plugin version is 3.0.1

Body:
Try to add the missing code from here

    buildscript {
        repositories {
            jcenter()
            google()
        }
        dependencies {
            classpath 'com.android.tools.build:gradle:3.0.1'
            classpath 'com.google.gms:google-services:3.0.0'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
    }

allprojects {
    repositories {
        jcenter()
        mavenCentral()
        maven {
            url "https://jitpack.io"
        }
        google()
    }
}

and add this to your build.gradle(Module:app)

dependencies {
    compile 'com.android.support:appcompat-v7:27.0.1'
    compile 'com.android.support:design:27.0.1'
    compile 'com.android.support:support-v4:27.0.1'
    }


问:
Pythonic way of sum of dot product of two list of lists
How can this be done elegantly (Pythonic way)

You have two matrices A and B represented each by a list of lists.

You would like to calculate the overall sum over the matrix of element-wise product of A and B.

sample code:

```<code>sum = 0
nrows = len(A)
ncols = len(A[0])
for i in range(nrows):
    for j in range(ncols):
        sum += A[i][j]*B[i][j]

# interested finally in the value of sum
# return sum
</code>```

for example if

A=[[1,2,3],[3,4,5]]

and

B=[[3,2,2],[1,1,1]]

the result is :

1*3 + 2*2 + 3*2 + 3*1 + 4*1 + 5*1 = 25

答:
```<code>import itertools

A = [[1,2,3],[3,4,5]]
B = [[3,2,2],[1,1,1]]

# flatten list A => [1,2,3,3,4,5]]
A_flat = itertools.chain.from_iterable(A)

# flatten list B = > [3,2,2,1,1,1]]
B_flat = itertools.chain.from_iterable(B)

# making sum of 1+3 , 2+2 , 3+2 result=> [4, 4, 5, 4, 5, 6]
pair_sum = [ sum(pair) for pair in zip(A_flat,B_flat)]

# total
print('Total : ', sum(pair_sum))

############

import itertools

A = [[1,2,3],[3,4,5]]
B = [[3,2,2],[1,1,1]]
A_flat = itertools.chain.from_iterable(A)
B_flat = itertools.chain.from_iterable(B)
total = sum(sum(pair) for pair in zip(A_flat,B_flat))
print(total)
</code>```

Body:
How can this be done elegantly (Pythonic way)

You have two matrices A and B represented each by a list of lists.

You would like to calculate the overall sum over the matrix of element-wise product of A and B.

sample code:

sum = 0
nrows = len(A)
ncols = len(A[0])
for i in range(nrows):
    for j in range(ncols):
        sum += A[i][j]*B[i][j]

# interested finally in the value of sum
# return sum

for example if

A=[[1,2,3],[3,4,5]]

and

B=[[3,2,2],[1,1,1]]

the result is :

1*3 + 2*2 + 3*2 + 3*1 + 4*1 + 5*1 = 25


问:
Why is my function running without asking for the input first?
So I am trying to work on a project for school and I wanted to create a prompt function that would allow me to enter in the question, type of prompt, the function that it would run if the input was "Y", and the response string it would output if the user replied "N".
This is my code:

```<code>#Will Steve Become a Millionaire?
#Interactive Fiction
#Zachary Williams

##Type 0 prompt = Y/N, Type 1 prompt = Int input.

def prompt(question, qType, yFunction, nResponse):
    print(question)

    answer=input()

    if qType==0:

        if answer=="Y" or answer=="y":
            yFunction()

        elif answer=="N" or answer=="n":
            print(nResponse)

        if answer=="X":
            print("test")

        else:
            print("\"" + answer + "\" is not one of the options. Please type \"Y\" or \"N\".")

    elif qType==1:
        print("test")

    else:
        print("Error creating prompt.")

##Start the story.
def start_program():
    print("It was 3:45 AM on a Saturday night. The only light in the room shone upon Steve's face, coming from the screen of his laptop, which he had been staring at for almost 12 hours straight. This was nothing new for Steve, but then an email popped up.")

    prompt("\nWould you like to read the email? (Y/N)", 0, open_email(), "Steve closed the notification. It was time to go to bed.")

def opening():
    print("Will Steve Become a Millionaire?")

    prompt("Starting the program.", 0, start_program(), "Okay then.")

def open_email():
    print("\nSteve opened the email.")
    print("\n\"I am Prince Kufour Otumfuo,\" the email read, \"I am transferring $75,000,000 USD to the United States, and need your help to transport it into the country. If you help me do so, I will only have you transfer $65,000,000 to my account, leaving you with $10,000,000 to keep. If you would be so kind, please reply to this email.\"")

opening()
</code>```

Currently, this is what it returns when I run the program:

Will Steve Become a Millionaire?
It was 3:45 AM on a Saturday night. The only light in the room shone upon Steve's face, coming from the screen of his laptop, which he had been staring at for almost 12 hours straight. This was nothing new for Steve, but then an email popped up.

Steve opened the email.

"I am Prince Kufour Otumfuo," the email read, "I am transferring $75,000,000 USD to the United States, and need your help to transport it into the country. If you help me do so, I will only have you transfer $65,000,000 to my account, leaving you with $10,000,000 to keep. If you would be so kind, please reply to this email."

Would you like to read the email? (Y/N)

Where it says "Steve opened the email." it should be asking "Would you like to read the email? (Y/N)", Instead, it's asking that after it prints it out. I'm very confused on why this is. Sorry if I didn't format this properly, I have never posted on here before.

Thanks!

答:
Change the below line in the opening() function from

```<code>prompt("Starting the program.", 0, start_program(), "Okay then.")
</code>```

To

```<code>prompt("Starting the program.", 0, start_program, "Okay then.")
</code>```

Note that I have removed the (). I think you need to pass the function object instead of calling the function.

Body:
So I am trying to work on a project for school and I wanted to create a prompt function that would allow me to enter in the question, type of prompt, the function that it would run if the input was "Y", and the response string it would output if the user replied "N".
This is my code:

#Will Steve Become a Millionaire?
#Interactive Fiction
#Zachary Williams

##Type 0 prompt = Y/N, Type 1 prompt = Int input.

def prompt(question, qType, yFunction, nResponse):
    print(question)

    answer=input()

    if qType==0:

        if answer=="Y" or answer=="y":
            yFunction()

        elif answer=="N" or answer=="n":
            print(nResponse)

        if answer=="X":
            print("test")

        else:
            print("\"" + answer + "\" is not one of the options. Please type \"Y\" or \"N\".")

    elif qType==1:
        print("test")

    else:
        print("Error creating prompt.")

##Start the story.
def start_program():
    print("It was 3:45 AM on a Saturday night. The only light in the room shone upon Steve's face, coming from the screen of his laptop, which he had been staring at for almost 12 hours straight. This was nothing new for Steve, but then an email popped up.")

    prompt("\nWould you like to read the email? (Y/N)", 0, open_email(), "Steve closed the notification. It was time to go to bed.")

def opening():
    print("Will Steve Become a Millionaire?")

    prompt("Starting the program.", 0, start_program(), "Okay then.")

def open_email():
    print("\nSteve opened the email.")
    print("\n\"I am Prince Kufour Otumfuo,\" the email read, \"I am transferring $75,000,000 USD to the United States, and need your help to transport it into the country. If you help me do so, I will only have you transfer $65,000,000 to my account, leaving you with $10,000,000 to keep. If you would be so kind, please reply to this email.\"")

opening()

Currently, this is what it returns when I run the program:

Will Steve Become a Millionaire?
It was 3:45 AM on a Saturday night. The only light in the room shone upon Steve's face, coming from the screen of his laptop, which he had been staring at for almost 12 hours straight. This was nothing new for Steve, but then an email popped up.

Steve opened the email.

"I am Prince Kufour Otumfuo," the email read, "I am transferring $75,000,000 USD to the United States, and need your help to transport it into the country. If you help me do so, I will only have you transfer $65,000,000 to my account, leaving you with $10,000,000 to keep. If you would be so kind, please reply to this email."

Would you like to read the email? (Y/N)

Where it says "Steve opened the email." it should be asking "Would you like to read the email? (Y/N)", Instead, it's asking that after it prints it out. I'm very confused on why this is. Sorry if I didn't format this properly, I have never posted on here before.

Thanks!

Body:
Change the below line in the opening() function from

prompt("Starting the program.", 0, start_program(), "Okay then.")

To

prompt("Starting the program.", 0, start_program, "Okay then.")

Note that I have removed the (). I think you need to pass the function object instead of calling the function.


问:
MySQL Workbench - Error in MySQL syntax
The MySQL workbench is a great tool, but you have to keep your head on as it does no error checking whatsoever.

So, it generated this SQL syntax to create a table and it won't work.
And I can't figure out WHY

It gives me this error:

```<code>#1064 - You have an error in your SQL syntax;
check the manual that corresponds to your MySQL server version
for the right syntax to use near
') NULL DEFAULT NULL , `maaltijd` TINYINT(1) NOT NULL ,
`cheques` TINYINT(1'
at line 14
</code>```

This is the query:

```<code>    CREATE  TABLE IF NOT EXISTS `nascholing`.`aanvraag` (
      `aanvraagId` INT(11) NOT NULL AUTO_INCREMENT ,
      `userId` BIGINT(20) NOT NULL ,
      `creationDate` DATETIME NULL DEFAULT NULL ,
      `vakGroep` INT(11) NULL DEFAULT NULL ,
      `personeelType` INT(11) NOT NULL ,
      `leeftijd` INT(11) NULL DEFAULT NULL ,
      `thema` VARCHAR(255) NOT NULL ,
      `intern` TINYINT(1) NULL DEFAULT -1 ,
      `duur` INT(11) NOT NULL ,
      `tijdens` INT(11) NULL DEFAULT NULL ,
      `type` INT(11) NULL DEFAULT NULL ,
      `voor` INT(11) NOT NULL ,
      `kost` DOUBLE(11) NULL DEFAULT NULL ,
      `maaltijd` TINYINT(1) NOT NULL ,
      `cheques` TINYINT(1) NOT NULL ,
      `betalingsmethode` INT(11) NOT NULL ,
      `aanschafBoek` TINYINT(1) NOT NULL ,
      `kostBoek` DOUBLE(11) NULL DEFAULT NULL ,
      PRIMARY KEY (`aanvraagId`) ,
      UNIQUE INDEX `aanvraagId_UNIQUE` (`aanvraagId` ASC) ,
      INDEX `fk_aanvraag_user1` (`userId` ASC) ,
      INDEX `fk_aanvraag_duur1` (`duur` ASC) ,
      INDEX `fk_aanvraag_tijdens1` (`tijdens` ASC) ,
      INDEX `fk_aanvraag_type1` (`type` ASC) ,
      INDEX `fk_aanvraag_vakGroep1` (`vakGroep` ASC) ,
      INDEX `fk_aanvraag_voorEmail1` (`voor` ASC) ,
      INDEX `fk_aanvraag_betalingsMethode1` (`betalingsmethode` ASC) ,
      CONSTRAINT `fk_aanvraag_user1`
        FOREIGN KEY (`userId` )
        REFERENCES `nascholing`.`user` (`userId` )
        ON DELETE NO ACTION
        ON UPDATE NO ACTION,
      CONSTRAINT `fk_aanvraag_duur1`
        FOREIGN KEY (`duur` )
        REFERENCES `nascholing`.`duur` (`duurId` )
        ON DELETE NO ACTION
        ON UPDATE NO ACTION,
      CONSTRAINT `fk_aanvraag_tijdens1`
        FOREIGN KEY (`tijdens` )
        REFERENCES `nascholing`.`tijdens` (`tijdensId` )
        ON DELETE NO ACTION
        ON UPDATE NO ACTION,
      CONSTRAINT `fk_aanvraag_type1`
        FOREIGN KEY (`type` )
        REFERENCES `nascholing`.`type` (`typeId` )
        ON DELETE NO ACTION
        ON UPDATE NO ACTION,
      CONSTRAINT `fk_aanvraag_vakGroep1`
        FOREIGN KEY (`vakGroep` )
        REFERENCES `nascholing`.`vakGroep` (`vakGroepId` )
        ON DELETE NO ACTION
        ON UPDATE NO ACTION,
      CONSTRAINT `fk_aanvraag_voorEmail1`
        FOREIGN KEY (`voor` )
        REFERENCES `nascholing`.`voorEmail` (`voorEmailId` )
        ON DELETE NO ACTION
        ON UPDATE NO ACTION,
      CONSTRAINT `fk_aanvraag_betalingsMethode1`
        FOREIGN KEY (`betalingsmethode` )
        REFERENCES `nascholing`.`betalingsMethode` (`betalingsMethodeId` )
        ON DELETE NO ACTION
        ON UPDATE NO ACTION)
    ENGINE = InnoDB
    DEFAULT CHARACTER SET = utf8
    COLLATE = utf8_general_ci;
</code>```

答:
There is a need to specify decimal point for type double

example,

```<code>`kost` DOUBLE(11, 2) NULL DEFAULT NULL, ...
</code>```

so on for all the type double

ContentLicense: CC BY-SA 2.5

Title: MySQL Workbench - Error in MySQL syntax

Body:
The MySQL workbench is a great tool, but you have to keep your head on as it does no error checking whatsoever.

So, it generated this SQL syntax to create a table and it won't work.
And I can't figure out WHY

It gives me this error:

#1064 - You have an error in your SQL syntax;
check the manual that corresponds to your MySQL server version
for the right syntax to use near
') NULL DEFAULT NULL , `maaltijd` TINYINT(1) NOT NULL ,
`cheques` TINYINT(1'
at line 14

This is the query:

    CREATE  TABLE IF NOT EXISTS `nascholing`.`aanvraag` (
      `aanvraagId` INT(11) NOT NULL AUTO_INCREMENT ,
      `userId` BIGINT(20) NOT NULL ,
      `creationDate` DATETIME NULL DEFAULT NULL ,
      `vakGroep` INT(11) NULL DEFAULT NULL ,
      `personeelType` INT(11) NOT NULL ,
      `leeftijd` INT(11) NULL DEFAULT NULL ,
      `thema` VARCHAR(255) NOT NULL ,
      `intern` TINYINT(1) NULL DEFAULT -1 ,
      `duur` INT(11) NOT NULL ,
      `tijdens` INT(11) NULL DEFAULT NULL ,
      `type` INT(11) NULL DEFAULT NULL ,
      `voor` INT(11) NOT NULL ,
      `kost` DOUBLE(11) NULL DEFAULT NULL ,
      `maaltijd` TINYINT(1) NOT NULL ,
      `cheques` TINYINT(1) NOT NULL ,
      `betalingsmethode` INT(11) NOT NULL ,
      `aanschafBoek` TINYINT(1) NOT NULL ,
      `kostBoek` DOUBLE(11) NULL DEFAULT NULL ,
      PRIMARY KEY (`aanvraagId`) ,
      UNIQUE INDEX `aanvraagId_UNIQUE` (`aanvraagId` ASC) ,
      INDEX `fk_aanvraag_user1` (`userId` ASC) ,
      INDEX `fk_aanvraag_duur1` (`duur` ASC) ,
      INDEX `fk_aanvraag_tijdens1` (`tijdens` ASC) ,
      INDEX `fk_aanvraag_type1` (`type` ASC) ,
      INDEX `fk_aanvraag_vakGroep1` (`vakGroep` ASC) ,
      INDEX `fk_aanvraag_voorEmail1` (`voor` ASC) ,
      INDEX `fk_aanvraag_betalingsMethode1` (`betalingsmethode` ASC) ,
      CONSTRAINT `fk_aanvraag_user1`
        FOREIGN KEY (`userId` )
        REFERENCES `nascholing`.`user` (`userId` )
        ON DELETE NO ACTION
        ON UPDATE NO ACTION,
      CONSTRAINT `fk_aanvraag_duur1`
        FOREIGN KEY (`duur` )
        REFERENCES `nascholing`.`duur` (`duurId` )
        ON DELETE NO ACTION
        ON UPDATE NO ACTION,
      CONSTRAINT `fk_aanvraag_tijdens1`
        FOREIGN KEY (`tijdens` )
        REFERENCES `nascholing`.`tijdens` (`tijdensId` )
        ON DELETE NO ACTION
        ON UPDATE NO ACTION,
      CONSTRAINT `fk_aanvraag_type1`
        FOREIGN KEY (`type` )
        REFERENCES `nascholing`.`type` (`typeId` )
        ON DELETE NO ACTION
        ON UPDATE NO ACTION,
      CONSTRAINT `fk_aanvraag_vakGroep1`
        FOREIGN KEY (`vakGroep` )
        REFERENCES `nascholing`.`vakGroep` (`vakGroepId` )
        ON DELETE NO ACTION
        ON UPDATE NO ACTION,
      CONSTRAINT `fk_aanvraag_voorEmail1`
        FOREIGN KEY (`voor` )
        REFERENCES `nascholing`.`voorEmail` (`voorEmailId` )
        ON DELETE NO ACTION
        ON UPDATE NO ACTION,
      CONSTRAINT `fk_aanvraag_betalingsMethode1`
        FOREIGN KEY (`betalingsmethode` )
        REFERENCES `nascholing`.`betalingsMethode` (`betalingsMethodeId` )
        ON DELETE NO ACTION
        ON UPDATE NO ACTION)
    ENGINE = InnoDB
    DEFAULT CHARACTER SET = utf8
    COLLATE = utf8_general_ci;

Body:
There is a need to specify decimal point for type double

example,

`kost` DOUBLE(11, 2) NULL DEFAULT NULL, ...

so on for all the type double


问:
how to disable a navigation bar button item in iOS
I have created a navigation controller. In the second view (which is pushed), I have some webservice call and placing a overlay view and setting

self.view.userInteractionEnabled = NO ;

Once web service call is complete, then I am reverting to

self.view.userInteractionEnabled = YES ;

When I do this, every other buttons except the buttons on the navigation bar are disabled. How to disable those two navigation bar button items ? (a button similar to back button, which pops to first view controller and another button which gives info about help).

I have tried using self.navigationItem.backBarButtonItem.enabled = NO. But still I am able to tap on the button and can navigate to first screen. How can I disable these two buttons ?

答:
Updated for Swift 3:

If you want to disable a navigation bar button item OR you want to disable hole UINavigationBar i.e. all item present on navigation bar, use below lines of code;

```<code>// if you want disable
self.navigationController?.navigationBar.isUserInteractionEnabled = false

// if you want enable again
self.navigationController?.navigationBar.isUserInteractionEnabled = true
</code>```

Enjoy...!

Body:
Updated for Swift 3:

If you want to disable a navigation bar button item OR you want to disable hole UINavigationBar i.e. all item present on navigation bar, use below lines of code;

// if you want disable
self.navigationController?.navigationBar.isUserInteractionEnabled = false

// if you want enable again
self.navigationController?.navigationBar.isUserInteractionEnabled = true

Enjoy...!


问:
Send mail with smtp SendAsync
this is how when I need to send email gives me error. But the mistake that since gives me is this:

An asynchronous operation cannot be started at this time. Asynchronous
  operations may only be started within an asynchronous handler or
  module or during certain events in the Page lifecycle. If this
  exception occurred while executing a Page, ensure that the Page is
  marked <%@ Page Async="true" %>. This exception may also indicate an
  attempt to call an "async void" method, which is generally unsupported
  within ASP.NET request processing. Instead, the asynchronous method
  should return a Task, and the caller should await it.

I have accumulated since the MVC and have used class to keep track of ie areas of the page. The reason I have used SendAsync is precisely that it goes a little faster to send email, etc..

This error only happens when I try to send email to users.

```<code>public static void NewPassword(string mail, string name, string password)
    {
        MailDefinition oMailDefinition = new MailDefinition();
        oMailDefinition.BodyFileName = "~/MailList/emailskabelon/NewPassword.html";
        oMailDefinition.From = FromMail;

        Dictionary<string, string> oReplacements = new Dictionary<string, string>();
        oReplacements.Add("<<navn>>", name);
        oReplacements.Add("<<password>>", password);

        System.Net.Mail.MailMessage oMailMessage = oMailDefinition.CreateMailMessage(mail, oReplacements, new LiteralControl());
        oMailMessage.Subject = NewpasswordTitle + WebsiteName;
        oMailMessage.IsBodyHtml = true;

        SmtpClient smtp = new SmtpClient(AzureApi);
        System.Net.NetworkCredential netcred = new System.Net.NetworkCredential(AzureName, AzurePassword);
        smtp.UseDefaultCredentials = false;
        smtp.EnableSsl = true;

        smtp.Credentials = netcred;
        smtp.Port = Convert.ToInt32("25");
        smtp.DeliveryMethod = SmtpDeliveryMethod.Network;

        using (var smtpClient = new SmtpClient())
        {
            smtp.SendAsync(oMailMessage, null);
        }
    }
</code>```

I've tried to do like this:

```<code>public static async NewPassword(string mail, string name, string password)
        {
            ....
            using (var smtpClient = new SmtpClient())
            {
                await smtp.SendAsync(oMailMessage, null);
            }
</code>```

i have see here: https://stackoverflow.com/a/35212320/7391454

答:
Not really replying your original question, but just wanted to stress that you are better off calling an email sending code without keeping the calling thread waiting. Although you are using async/await, in user's perspective, you are still waiting in the browser while the server is done sending emails. It may be few milliseconds, but still it's better to let this handled by a background worker.

So IMO, using HostingEnvironment.QueueBackgroundWorkItem(x=> SendEmail()); would be a better approach.

Having said that, you still have a slight risk of the asynchronous task being terminated if app domain recycles in the middle. But that's highly unlikely in your case I would say. Even if that happens, you can use a cancellation token and work your way around it.

Title: Send mail with smtp SendAsync

Body:
this is how when I need to send email gives me error. But the mistake that since gives me is this:

An asynchronous operation cannot be started at this time. Asynchronous
  operations may only be started within an asynchronous handler or
  module or during certain events in the Page lifecycle. If this
  exception occurred while executing a Page, ensure that the Page is
  marked <%@ Page Async="true" %>. This exception may also indicate an
  attempt to call an "async void" method, which is generally unsupported
  within ASP.NET request processing. Instead, the asynchronous method
  should return a Task, and the caller should await it.

I have accumulated since the MVC and have used class to keep track of ie areas of the page. The reason I have used SendAsync is precisely that it goes a little faster to send email, etc..

This error only happens when I try to send email to users.

public static void NewPassword(string mail, string name, string password)
    {
        MailDefinition oMailDefinition = new MailDefinition();
        oMailDefinition.BodyFileName = "~/MailList/emailskabelon/NewPassword.html";
        oMailDefinition.From = FromMail;

        Dictionary<string, string> oReplacements = new Dictionary<string, string>();
        oReplacements.Add("<<navn>>", name);
        oReplacements.Add("<<password>>", password);

        System.Net.Mail.MailMessage oMailMessage = oMailDefinition.CreateMailMessage(mail, oReplacements, new LiteralControl());
        oMailMessage.Subject = NewpasswordTitle + WebsiteName;
        oMailMessage.IsBodyHtml = true;

        SmtpClient smtp = new SmtpClient(AzureApi);
        System.Net.NetworkCredential netcred = new System.Net.NetworkCredential(AzureName, AzurePassword);
        smtp.UseDefaultCredentials = false;
        smtp.EnableSsl = true;

        smtp.Credentials = netcred;
        smtp.Port = Convert.ToInt32("25");
        smtp.DeliveryMethod = SmtpDeliveryMethod.Network;

        using (var smtpClient = new SmtpClient())
        {
            smtp.SendAsync(oMailMessage, null);
        }
    }

I've tried to do like this:

public static async NewPassword(string mail, string name, string password)
        {
            ....
            using (var smtpClient = new SmtpClient())
            {
                await smtp.SendAsync(oMailMessage, null);
            }

i have see here: https://stackoverflow.com/a/35212320/7391454


问:
How to add google maps api key during deployment (on heroku ) and how to use development / production keys?
I want to deploy something on heroku which includes a google map.
In my script I used

```<code>script src="https://maps.googleapis.com/maps/api/js?key=YOUR_KEY&callback=myMap"></script>
</code>```

on heroku, I added to environment variables the actual google map api key I received. The map is still not showing up in production and I wonder what I did wrong.

Also, a general question as Im not too familiar with development/production variables. I understand its important for security reasons. So in my script do I have to create 2 files- 1 for production where I include the actual key and a development file which would not include the actual key? Thats what I've seen doing some research but I wonder:

If I do have those 2 files, how come the production script with the actual key can't be 'seen' while the development file can?

Do I need to create 2 scripts or can I just use a script tag (like I did with google maps) where I don't include the key and do it while deployment?

It would be cool if someone could explain this to me!! Thanks a lot!

答:
You may need to precompile the JavaScript assets and push them to the Heroku server.

Try this:

```<code>rake assets:precompile
git add .
git commit -m "message"
git push heroku master
git push origin master
</code>```

Body:
I want to deploy something on heroku which includes a google map.
In my script I used

script src="https://maps.googleapis.com/maps/api/js?key=YOUR_KEY&callback=myMap"></script>

on heroku, I added to environment variables the actual google map api key I received. The map is still not showing up in production and I wonder what I did wrong.

Also, a general question as Im not too familiar with development/production variables. I understand its important for security reasons. So in my script do I have to create 2 files- 1 for production where I include the actual key and a development file which would not include the actual key? Thats what I've seen doing some research but I wonder:

If I do have those 2 files, how come the production script with the actual key can't be 'seen' while the development file can?

Do I need to create 2 scripts or can I just use a script tag (like I did with google maps) where I don't include the key and do it while deployment?

It would be cool if someone could explain this to me!! Thanks a lot!

Body:
You may need to precompile the JavaScript assets and push them to the Heroku server.

Try this:

rake assets:precompile
git add .
git commit -m "message"
git push heroku master
git push origin master


问:
WinForms WebBrowser - FireBug Inspect Element-like highlighting
Basically, I need to load any HTML document in WebBrowser control and allow users to visually select one or more HTML DOM elements (in order to get their XPaths, but that's another story).

Hovering an element will highlight it with color A, moving mouse out will restore it's visual state.

Clicking an element will highlight it with color B, clicking again previously clicked element will restore it's visual state.

To summarize, it should behave like the FireBug Inspect Element feature, or like the Dapp Factory Select Content feature.

A naive approach would be to use HtmlElement.Style property like in the example below, but obviously I can't because the element could already have the border style set in the same manner in which case it should not be removed on MouseLeave:

```<code>void Document_MouseOver(object sender, HtmlElementEventArgs e)
{
    // what if e.FromElement.Style already contains "border: solid 1px Red;" ?
    e.FromElement.Style = "border: solid 1px Red; " + e.FromElement.Style;
    [...]
}
</code>```

Possibly I could achieve this by setting/unsetting a custom CSS class (like one would do using JavaScript in the same case), but HtmlElement does not seem to expose such a property, and how would I inject CSS class definitions anyway?

Update: it is actually possible to set the CSS class with HtmlElement.SetAttribute("className"); to inject CSS classes, check for example C#: Best way to inject CSS into MSHTML instance?.

Any ideas on how to achieve this are welcome. Thank you.

答: IHighlightRenderingServices</p>

Body:
Basically, I need to load any HTML document in WebBrowser control and allow users to visually select one or more HTML DOM elements (in order to get their XPaths, but that's another story).

Hovering an element will highlight it with color A, moving mouse out will restore it's visual state.

Clicking an element will highlight it with color B, clicking again previously clicked element will restore it's visual state.

To summarize, it should behave like the FireBug Inspect Element feature, or like the Dapp Factory Select Content feature.

A naive approach would be to use HtmlElement.Style property like in the example below, but obviously I can't because the element could already have the border style set in the same manner in which case it should not be removed on MouseLeave:

void Document_MouseOver(object sender, HtmlElementEventArgs e)
{
    // what if e.FromElement.Style already contains "border: solid 1px Red;" ?
    e.FromElement.Style = "border: solid 1px Red; " + e.FromElement.Style;
    [...]
}

Possibly I could achieve this by setting/unsetting a custom CSS class (like one would do using JavaScript in the same case), but HtmlElement does not seem to expose such a property, and how would I inject CSS class definitions anyway?

Update: it is actually possible to set the CSS class with HtmlElement.SetAttribute("className"); to inject CSS classes, check for example C#: Best way to inject CSS into MSHTML instance?.

Any ideas on how to achieve this are welcome. Thank you.

Body: IHighlightRenderingServices


问:
Pandas create column conditional on others
I have a dataframe like

```<code>df = pd.DataFrame({'tag':['x','x','z','z','x','z'], 'val':[1,2,3,1,2,3]})
</code>```

Is there a one-liner to add a column 'res' that shows -val if tag=='x' otherwise +val, so it would look like

```<code>  tag  val  res
0   x    1   -1
1   x    2   -2
2   z    3    3
3   z    1    1
4   x    2   -2
5   z    3    3
</code>```

答:
You can do this with apply:

```<code>df['res'] = df.apply(
              lambda x: x['val'] if not x['tag'] == 'x' else (-1 * x['val']), axis=1)
</code>```

Body:
I have a dataframe like

df = pd.DataFrame({'tag':['x','x','z','z','x','z'], 'val':[1,2,3,1,2,3]})

Is there a one-liner to add a column 'res' that shows -val if tag=='x' otherwise +val, so it would look like

  tag  val  res
0   x    1   -1
1   x    2   -2
2   z    3    3
3   z    1    1
4   x    2   -2
5   z    3    3

Body:
You can do this with apply:

df['res'] = df.apply(
              lambda x: x['val'] if not x['tag'] == 'x' else (-1 * x['val']), axis=1)


问:
JMeter, BeanShell Assertion comparison multiple iterations
I have a problem. In my test case, every iteration has a response different or different number variables, depends on data input. Example. The first iteration responds one code and one description; the Second iteration responds two codes and two descriptions; and similar. I need insert a BeanShell Assertion to validate the response every iteration.
First step: add a TWO Regular Expression Extractor (one for each variable)

My code in BeanShell Assertion not working; only extract the first value for each RegEx Extractor

String Resp_clave_g1 = vars.get("Resp_clave_g1"); //Obtained from Regular Expresion Extractor
String Resp_descripcion_g1 = vars.get("Resp_descripcion_g1"); //Obtained from Regular Expresion Extractor
String Resp_clave_g2 = vars.get("Resp_clave_g2"); //Obtained from Regular Expresion Extractor
String Resp_descripcion_g2 = vars.get("Resp_descripcion_g2"); //Obtained from Regular Expresion Extractor
String Resp_clave_g3 = vars.get("Resp_clave_g3"); //Obtained from Regular Expresion Extractor
String Resp_descripcion_g3 = vars.get("Resp_descripcion_g3"); //Obtained from Regular Expresion Extractor
String Resp_clave_g4 = vars.get("Resp_clave_g4"); //Obtained from Regular Expresion Extractor
String Resp_descripcion_g4 = vars.get("Resp_descripcion_g4"); //Obtained from Regular Expresion Extractor
String Resp_clave_g5 = vars.get("Resp_clave_g5"); //Obtained from Regular Expresion Extractor
String Resp_descripcion_g5 = vars.get("Resp_descripcion_g5"); //Obtained from Regular Expresion Extractor
String Resp_clave_g6 = vars.get("Resp_clave_g6"); //Obtained from Regular Expresion Extractor
String Resp_descripcion_g6 = vars.get("Resp_descripcion_g6"); //Obtained from Regular Expresion Extractor

log.warn (Resp_clave_g1);
log.warn (Resp_descripcion_g1);
log.warn (Resp_clave_g2);
log.warn (Resp_descripcion_g2);
log.warn (Resp_clave_g3);
log.warn (Resp_descripcion_g3);
log.warn (Resp_clave_g4);
log.warn (Resp_descripcion_g4);
log.warn (Resp_clave_g5);
log.warn (Resp_descripcion_g5);
log.warn (Resp_clave_g6);
log.warn (Resp_descripcion_g6);

if (Resp_clave_g1 != null && Resp_clave_g1.equals("${clave_1}") == false){ //Obtained from DataSet CSV
  Failure = true;
 FailureMessage = "Not a valid string, expected: ${clave_1}, actual value: " + Resp_clave_g1;
}else{
 Failure = false;
}```

答:
You missed changing Match No. to negative number as -1 to return all occurrences

If the match number is set to a negative number, then all the possible matches in the sampler data are processed.


问:
Can't use the iOS distribution in Xcode
In my Xcode 9 project I have the Automatically manage signing checked. I want to sign the application with the iOS distribution certificate. For some reasons, when I was creating the certificate I entered the name and email of another person. In the keychain Access I can see the public and private keys with the name of that person and under the private one, the iPhone distribution certificate. The problem is that in Xcode when I select the Team, I'm only getting the iPhone developer signing certificate and not the the distribution one. But from the Build Setting I can see the iPhone distribution in the select list of the Code Signing Identity. Once I select it, Xcode detect a conflict of the provisioning profile (because I change it manually and the Automatically manage signing is checked). I tried the solution of check then uncheck it and select the team but the problem is still here.

答:
Make sure your Scheme under the Left top corner of App name Dropdown-->Edit Scheme is enabled to Release and not Debug for Archive and Testing also so automatically your Distribution is selected. </p>

<p>When you use the Automatic provisioning by default you are getting two profiles generated in Xocde One when you connect the device it used Dev Profile for debugging, but when you archive the build it autogenerates Distribution profile. If you have enterprise account, I would recommend having a universal distribution profile created and not Adhoc as it will always have to be updated with new Device ID added to be regenerated and recompiled the old app. </p>

Title: Can't use the iOS distribution in Xcode

Body:
Make sure your Scheme under the Left top corner of App name Dropdown-->Edit Scheme is enabled to Release and not Debug for Archive and Testing also so automatically your Distribution is selected.

When you use the Automatic provisioning by default you are getting two profiles generated in Xocde One when you connect the device it used Dev Profile for debugging, but when you archive the build it autogenerates Distribution profile. If you have enterprise account, I would recommend having a universal distribution profile created and not Adhoc as it will always have to be updated with new Device ID added to be regenerated and recompiled the old app.


问:
Python/P2P - Unable to connect to rendezvous server
I am trying to create a P2P node using python (pyp2p) but I am getting this error:

```<code>Eamons-MacBook-Pro:blockchain eamonwhite$ python3 serveralice.py
HTTP Error 404: Not Found
HTTP Error 404: Not Found
HTTP Error 404: Not Found
HTTP Error 404: Not Found
Traceback (most recent call last):
  File "/Users/eamonwhite/.pyenv/versions/3.6.3/lib/python3.6/site-packages/pyp2p/net.py", line 732, in start
    rendezvous_con = self.rendezvous.server_connect()
  File "/Users/eamonwhite/.pyenv/versions/3.6.3/lib/python3.6/site-packages/pyp2p/rendezvous_client.py", line 92, in server_connect
    con.connect(server["addr"], server["port"])
  File "/Users/eamonwhite/.pyenv/versions/3.6.3/lib/python3.6/site-packages/pyp2p/sock.py", line 189, in connect
    self.s.bind((src_ip, 0))
TypeError: str, bytes or bytearray expected, not NoneType

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "serveralice.py", line 10, in <module>
    alice.start()
  File "/Users/eamonwhite/.pyenv/versions/3.6.3/lib/python3.6/site-packages/pyp2p/net.py", line 735, in start
    raise Exception("Unable to connect to rendezvous server.")
Exception: Unable to connect to rendezvous server.
</code>```

My relevant code looks like this:

```<code>from uuid import uuid4
from blockchain import Blockchain
from flask import Flask, jsonify, request
from pyp2p.net import *
import time

#Setup Alice's p2p node.
alice = Net(passive_bind="192.168.1.131", passive_port=44444, interface="en0", node_type="passive", debug=1)
alice.start()
alice.bootstrap()
alice.advertise()

while 1:
    for con in alice:
        for reply in con:
            print(reply)

    time.sleep(1)

...
</code>```

It is getting stuck on the Net function right at the beginning - something to do with the rendezvous package. The IP is my IP on the my network, and I port forwarded 44444 although I'm not sure if I need to do that or not. Thanks.

答:
I am new to this, apparently with the way the server code was configured, it needed a rendezvous server to work (a node that handles all the other nodes). It is in net.py of the pyp2p package:

```<code># Bootstrapping + TCP hole punching server.
rendezvous_servers = [
    {
        "addr": "162.243.213.95",
        "port": 8000
    }
]
</code>```

The address was the problem, obviously it is just a placeholder IP. So then I realized I needed my own rendezvous server, and I used this code - https://raw.githubusercontent.com/StorjOld/pyp2p/master/pyp2p/rendezvous_server.py.

However I had to debug this file a little, it ended up needing to have import sys, import time and import re statements at the top before it would work. Now I am going to host it on my raspberry pi so that it is always up to handle nodes :)

Body:
I am trying to create a P2P node using python (pyp2p) but I am getting this error:

Eamons-MacBook-Pro:blockchain eamonwhite$ python3 serveralice.py
HTTP Error 404: Not Found
HTTP Error 404: Not Found
HTTP Error 404: Not Found
HTTP Error 404: Not Found
Traceback (most recent call last):
  File "/Users/eamonwhite/.pyenv/versions/3.6.3/lib/python3.6/site-packages/pyp2p/net.py", line 732, in start
    rendezvous_con = self.rendezvous.server_connect()
  File "/Users/eamonwhite/.pyenv/versions/3.6.3/lib/python3.6/site-packages/pyp2p/rendezvous_client.py", line 92, in server_connect
    con.connect(server["addr"], server["port"])
  File "/Users/eamonwhite/.pyenv/versions/3.6.3/lib/python3.6/site-packages/pyp2p/sock.py", line 189, in connect
    self.s.bind((src_ip, 0))
TypeError: str, bytes or bytearray expected, not NoneType

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "serveralice.py", line 10, in <module>
    alice.start()
  File "/Users/eamonwhite/.pyenv/versions/3.6.3/lib/python3.6/site-packages/pyp2p/net.py", line 735, in start
    raise Exception("Unable to connect to rendezvous server.")
Exception: Unable to connect to rendezvous server.

My relevant code looks like this:

from uuid import uuid4
from blockchain import Blockchain
from flask import Flask, jsonify, request
from pyp2p.net import *
import time

#Setup Alice's p2p node.
alice = Net(passive_bind="192.168.1.131", passive_port=44444, interface="en0", node_type="passive", debug=1)
alice.start()
alice.bootstrap()
alice.advertise()

while 1:
    for con in alice:
        for reply in con:
            print(reply)

    time.sleep(1)

...

It is getting stuck on the Net function right at the beginning - something to do with the rendezvous package. The IP is my IP on the my network, and I port forwarded 44444 although I'm not sure if I need to do that or not. Thanks.

Body:
I am new to this, apparently with the way the server code was configured, it needed a rendezvous server to work (a node that handles all the other nodes). It is in net.py of the pyp2p package:

# Bootstrapping + TCP hole punching server.
rendezvous_servers = [
    {
        "addr": "162.243.213.95",
        "port": 8000
    }
]

The address was the problem, obviously it is just a placeholder IP. So then I realized I needed my own rendezvous server, and I used this code - https://raw.githubusercontent.com/StorjOld/pyp2p/master/pyp2p/rendezvous_server.py.

However I had to debug this file a little, it ended up needing to have import sys, import time and import re statements at the top before it would work. Now I am going to host it on my raspberry pi so that it is always up to handle nodes :)


问:
Java Swing aligning buttons, labels, and text fields
I am trying to align my JButton and JTextArea to the bottom middle of my code, side by side. I followed a few tutorials and came to this point. When I execute my program, the text area and the button are still both aligned at the top. Help!</p>

```<code>import java.awt.BorderLayout;
import java.awt.FlowLayout;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class Main extends JFrame implements ActionListener{

JPanel panel = new JPanel();
JButton button = new JButton("Confirm!");
JTextArea text = new JTextArea(1, 20);
public Main() {
    super("Battleship!");
    setLayout(new FlowLayout());
    button.addActionListener(this);
    setSize(600, 500);
    setResizable(true);
    button.setLayout(new FlowLayout(FlowLayout.CENTER));
    text.setLayout(new FlowLayout(FlowLayout.CENTER));
    panel.add(text, BorderLayout.SOUTH);
    panel.add(button, BorderLayout.SOUTH);
    add(panel);

    setVisible(true);
}
public static void main(String[] args) {
    new Main();
}
@Override
public void actionPerformed(ActionEvent e) {
    button.setText(text.getText());
}

}
</code>```

答:
There is no need of setting any flow layout to button or text for placing in center because panel has by default "FlowLayout center" which will place the components in center
And frame has by default "BorderLayout"

To place the button and textarea at the bottom you only need to add both of them in panel(which you already done) and then add panel to frame with parameter as BorderLayout.SOUTH
Seee the modified code below it will work as per your need

```<code> import java.awt.BorderLayout;
 import java.awt.FlowLayout;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import javax.swing.*;
 public class Main extends JFrame implements ActionListener
 {
      JPanel panel = new JPanel();
      JButton button = new JButton("Confirm!");
      JTextArea text = new JTextArea(1, 20);
      public Main()
      {
          super("Battleship!");
          button.addActionListener(this);
          setSize(600, 500);
          setResizable(true);
          panel.add(text);
          panel.add(button);
          add(panel, BorderLayout.SOUTH);
          setVisible(true);
      }
      public static void main(String[] args)
      {
          new Main();
      }
      @Override public void actionPerformed(ActionEvent e)
      {
           button.setText(text.getText());
      }
 }
</code>```

Body:
I am trying to align my JButton and JTextArea to the bottom middle of my code, side by side. I followed a few tutorials and came to this point. When I execute my program, the text area and the button are still both aligned at the top. Help!

import java.awt.BorderLayout;
import java.awt.FlowLayout;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class Main extends JFrame implements ActionListener{

JPanel panel = new JPanel();
JButton button = new JButton("Confirm!");
JTextArea text = new JTextArea(1, 20);
public Main() {
    super("Battleship!");
    setLayout(new FlowLayout());
    button.addActionListener(this);
    setSize(600, 500);
    setResizable(true);
    button.setLayout(new FlowLayout(FlowLayout.CENTER));
    text.setLayout(new FlowLayout(FlowLayout.CENTER));
    panel.add(text, BorderLayout.SOUTH);
    panel.add(button, BorderLayout.SOUTH);
    add(panel);

    setVisible(true);
}
public static void main(String[] args) {
    new Main();
}
@Override
public void actionPerformed(ActionEvent e) {
    button.setText(text.getText());
}

}

Body:
There is no need of setting any flow layout to button or text for placing in center because panel has by default "FlowLayout center" which will place the components in center
And frame has by default "BorderLayout"

To place the button and textarea at the bottom you only need to add both of them in panel(which you already done) and then add panel to frame with parameter as BorderLayout.SOUTH
Seee the modified code below it will work as per your need

 import java.awt.BorderLayout;
 import java.awt.FlowLayout;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import javax.swing.*;
 public class Main extends JFrame implements ActionListener
 {
      JPanel panel = new JPanel();
      JButton button = new JButton("Confirm!");
      JTextArea text = new JTextArea(1, 20);
      public Main()
      {
          super("Battleship!");
          button.addActionListener(this);
          setSize(600, 500);
          setResizable(true);
          panel.add(text);
          panel.add(button);
          add(panel, BorderLayout.SOUTH);
          setVisible(true);
      }
      public static void main(String[] args)
      {
          new Main();
      }
      @Override public void actionPerformed(ActionEvent e)
      {
           button.setText(text.getText());
      }
 }