问:
Multiple conditional value replacement for the purpose of tidying data

Code        Type
123456      1
1234567     1
12345678    1
A123456     1
12345678    1
            1
2345678     2```
</div>
</div>
</p>

<p>I am trying to prepend 0 to values in the Code column if two criteria are met:
i) the Code value is a number (does not include letters or NA).
ii) the type column is equal to 1
This is so that certain values are a uniform 8 characters for an API request I am building.</p>

<p>
I have tried using the following:</p>

```  if(Type = 1 & !is.na(Code)) {
        with_options(
        c(scipen = 999),
        str_pad(Code, 8, pad = "0")
        )
    }
```

<p>for the above example I'd expect row one to update to 00123456, row two to 01234567. All the other examples should stay the same.</p>

<p>
I get the following error</p>

```Warning message:
In if (Type = 1 & !is.na(Code)) { :
  the condition has length > 1 and only the first element will be used
```

I have tried doing this in multiple ways and still get an error.

答:
This should solve your problem. I'm using dplyr for better readability, but it could also be implemented without it (using base ifelse)

```<code>library(stringr)
library(dplyr)

data <-
  structure(list(Code = c("123456", "1234567", "12345678", "A123456", "12345678", "", "2345678"),
                 Type = c(1L, 1L, 1L, 1L, 1L, 1L, 2L)), .Names = c("Code", "Type"),
            class = "data.frame", row.names = c(NA, -7L))

data %>%
  mutate(Code_new = if_else(!str_detect(Code, "[^\\d]") & Type == 1,
                            str_pad(data$Code, width = 8, side = "left", pad = "0"),
                            Code))
#       Code Type Code_new
# 1   123456    1 00123456
# 2  1234567    1 01234567
# 3 12345678    1 12345678
# 4  A123456    1  A123456
# 5 12345678    1 12345678
# 6             1 00000000
# 7  2345678    2  2345678
</code>```

Explanation:
First I check the conditions for modifying the Code column with
 !str_detect(Code, "[^\\d]") & Type == 1.

If you want to ensure, that there's at least one digit in your Code variable, add

& str_detect(Code, "\\d") to the conditions.

If the conditions are met, then the Code is padded with 0s, otherwise the original Code entry is returned.
Using if_else instead of ifelse ensures, that the TRUE and FALSE statements return the same vector type.

Body:
Code        Type
123456      1
1234567     1
12345678    1
A123456     1
12345678    1
            1
2345678     2

I am trying to prepend 0 to values in the Code column if two criteria are met:
i) the Code value is a number (does not include letters or NA).
ii) the type column is equal to 1
This is so that certain values are a uniform 8 characters for an API request I am building.

I have tried using the following:

  if(Type = 1 & !is.na(Code)) {
        with_options(
        c(scipen = 999),
        str_pad(Code, 8, pad = "0")
        )
    }

for the above example I'd expect row one to update to 00123456, row two to 01234567. All the other examples should stay the same.

I get the following error

Warning message:
In if (Type = 1 & !is.na(Code)) { :
  the condition has length > 1 and only the first element will be used

I have tried doing this in multiple ways and still get an error.

Body:
This should solve your problem. I'm using dplyr for better readability, but it could also be implemented without it (using base ifelse)

library(stringr)
library(dplyr)

data <-
  structure(list(Code = c("123456", "1234567", "12345678", "A123456", "12345678", "", "2345678"),
                 Type = c(1L, 1L, 1L, 1L, 1L, 1L, 2L)), .Names = c("Code", "Type"),
            class = "data.frame", row.names = c(NA, -7L))

data %>%
  mutate(Code_new = if_else(!str_detect(Code, "[^\\d]") & Type == 1,
                            str_pad(data$Code, width = 8, side = "left", pad = "0"),
                            Code))
#       Code Type Code_new
# 1   123456    1 00123456
# 2  1234567    1 01234567
# 3 12345678    1 12345678
# 4  A123456    1  A123456
# 5 12345678    1 12345678
# 6             1 00000000
# 7  2345678    2  2345678

Explanation:
First I check the conditions for modifying the Code column with
 !str_detect(Code, "[^\\d]") & Type == 1.

If you want to ensure, that there's at least one digit in your Code variable, add

& str_detect(Code, "\\d") to the conditions.

If the conditions are met, then the Code is padded with 0s, otherwise the original Code entry is returned.
Using if_else instead of ifelse ensures, that the TRUE and FALSE statements return the same vector type.


来源: stackexchange

问:
Failed to build an existing application due to lack of jcenter certificate - blocked by gradle
I tried to build an andruid application using latest andruid studio
Seems that gradle is blocked due to lack of jcenter certificate in local machine certstore. My colleguee succeed to build it on his machine so the problem is in the configuration and not the application code

Configuration :  andruid studio 3.0.1, gradle 3.0.0 ?, windows 7

I also tried to workaround ssl handshake by replacing jcenter() in build.gradle with

```<code> maven {
            url  "http://jcenter.bintray.com"
        }
</code>```

but it didn't solve the problem

My build.gradle below:

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

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

allprojects {
    repositories {
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}
</code>```

Gradle console:

```<code>Executing tasks: [assemble]

Configuration on demand is an incubating feature.

FAILURE: Build failed with an exception.

* What went wrong:
A problem occurred configuring root project 'PDA'.
> Could not resolve all files for configuration ':classpath'.
   > Could not resolve com.android.tools.build:gradle:3.0.0.
     Required by:
         project :
      > Could not resolve com.android.tools.build:gradle:3.0.0.
         > Could not get resource 'http://jcenter.bintray.com/com/android/tools/build/gradle/3.0.0/gradle-3.0.0.pom'.
            > Could not HEAD 'http://jcenter.bintray.com/com/android/tools/build/gradle/3.0.0/gradle-3.0.0.pom'.
               > Connect to repo.jfrog.org:80 [repo.jfrog.org/52.72.224.151, repo.jfrog.org/34.204.33.255] failed: Connection timed out: connect
</code>```

答:
The plugin v.3.x.x

```<code> classpath 'com.android.tools.build:gradle:3.0.0'
</code>```

is not in jcenter.

You have to use the google maven repo.

```<code>buildscript {
    repositories {
        jcenter()
        maven {
            url "https://maven.google.com"
        }
    }
}
</code>```

If you are using Android Studio 3 and gradle v.4.x you can use the google() shortcut

```<code>buildscript {
    repositories {
        ...
        google()
    }
}
</code>```

ContentLicense: CC BY-SA 3.0

Body:
I tried to build an andruid application using latest andruid studio
Seems that gradle is blocked due to lack of jcenter certificate in local machine certstore. My colleguee succeed to build it on his machine so the problem is in the configuration and not the application code

Configuration :  andruid studio 3.0.1, gradle 3.0.0 ?, windows 7

I also tried to workaround ssl handshake by replacing jcenter() in build.gradle with

 maven {
            url  "http://jcenter.bintray.com"
        }

but it didn't solve the problem

My build.gradle below:

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.0.0'

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

allprojects {
    repositories {
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

Gradle console:

Executing tasks: [assemble]

Configuration on demand is an incubating feature.

FAILURE: Build failed with an exception.

* What went wrong:
A problem occurred configuring root project 'PDA'.
> Could not resolve all files for configuration ':classpath'.
   > Could not resolve com.android.tools.build:gradle:3.0.0.
     Required by:
         project :
      > Could not resolve com.android.tools.build:gradle:3.0.0.
         > Could not get resource 'http://jcenter.bintray.com/com/android/tools/build/gradle/3.0.0/gradle-3.0.0.pom'.
            > Could not HEAD 'http://jcenter.bintray.com/com/android/tools/build/gradle/3.0.0/gradle-3.0.0.pom'.
               > Connect to repo.jfrog.org:80 [repo.jfrog.org/52.72.224.151, repo.jfrog.org/34.204.33.255] failed: Connection timed out: connect

Body:
The plugin v.3.x.x

 classpath 'com.android.tools.build:gradle:3.0.0'

is not in jcenter.

You have to use the google maven repo.

buildscript {
    repositories {
        jcenter()
        maven {
            url "https://maven.google.com"
        }
    }
}

If you are using Android Studio 3 and gradle v.4.x you can use the google() shortcut

buildscript {
    repositories {
        ...
        google()
    }
}


问:
Suggestions for dealing with IE's terrible Javascript / Dom accessing engine
I'm working on a site that has a page that can potentially become very long.  It can have in theory 1000+ rows of data in it.  Then these rows could each have sub-rows.

I'm currently using a list / sublist structure to represent the data because it's difficult to visualize subsets in tables.  the subset data is in a table though.

The Problem is this:  In IE.   my hovering over the row styles,  tooltips and other javascripts are taking upwards of 5 seconds to fire!   The page hangs like crazy and is pretty much unuseable.  In FF, Chrome, and Safari it works just fine.

I don't need a whole bunch of stats saying IE is slow. i know it is. what i need is some suggestions / theories/ ideas on how to combat the slowness!

Some of the ideas i've had so far:
-some kind of paging mechanism.   But that gets tricky b/c 1.  It's a list not a table, and 2.  it's got sub sub lists and sub tables for those sub lists.   so we'd need to somehow page based on the top level i think.  because we don't want to split the data up at all.    I guess that might be feasible...

-some kind of mechanism that holds the content in a javascript array or object or soomething and doesn't add it to the dom until it's been scrolled to.   and takes it away when you scroll past it.  in theory this would be cool. but i think it would be horrible to impliment.

-something else entirely?

Thanks in Advance for any ideas!  I'm probably going to try and put a bounty on this as soon as i'm able to help inspire you ;)

EDIT:

OH MY!  I think i may have found part of the problem using dyna trace!  thanks Pointy for reminding me about this tool. i had forgotten about out.   the click event of one of my buttons seems to be firing an insane amount.  like 2000 times and count.  something is clicking it automatically or something crazy like that.   weird thing is, i don't have any javascripts that trigger that button click!  EDIT:  This doesn't seem to be an issue anymore.

EDIT:

Also: i don't think it is the complexity of my markup that is affecting the responsiveness of my scripts(i know if i could use just id selectors it would be best, but i've optimized my selectors and qtips as much as possible (with help from s.o. in the past).  i have a button that is just on the page, not nested in anything,  that the click handler takes 4 or 5 seconds to register.  It's not that the click action takes a long time, it's just slow to notice that it's been clicked.

EDIT: i had 5 spans that were each nested in a span unnecessarily,  i un-nested those and it seems to have cut the slowness in about 1/2!!    (these 5 spans were repeated in every row)

EDIT:   Here's some of the relevant scripts:

The Main Button Handler:

```<code>$('#FilterScheduledShifts').click(function () {
  var categoryId = $('#CategoryId').val();
  var activityId = $('#ActivityId').val();
  var shiftStatusFilters = GetShiftStatusFilterIds();
  var dayOfWeekFilters = GetDayOfWeekFilters();
  var startDateFilter = GetStartDateFilter();
  var endDateFilter = GetStartEndFilter();
  var dataToPost = {
    categoryId: categoryId,
    activityId: activityId,
    statuses: shiftStatusFilters,
    daysOfWeek: dayOfWeekFilters,
    startDate: startDateFilter,
    endDate: endDateFilter
  };
  var url = $('#UrlToFilter').val();
  $('#ListHolder').html("<%=web.loading %>");
  $.ajax({
    url: url,
    data: dataToPost,
    type: 'POST',
    success: function (data) {
      document.getElementById('ScheduledActivityShiftListHolder').innerHTML = data;
    },
    error: function () {
      v2ErrorNotice(v2Text.shared.genericAjaxErrorMessage);
    }
  });
});
</code>```

The Get...FIlter functions are very simple functions that run in a few milliseconds... nothing interesting or noteworthy happening in there.

this bit attaches some of the behaviour that is very slow:
in other pages they react nice and quick, on this page... 2-3 seconds.

```<code>$('span.infoCard').die();
$('span.infoCard').live("mouseover", function () {

  var $this = $(this);
  if (!$this.data("toolTipAttached")) {

    var title = '';

    if ($this.attr('infoCardTitle') != "") {
      title = $this.attr('infoCardTitle');
    } else {
      title = $this.html();
    }

    $this.qtip({
      content: {
        text: "loading",
        title: title,
        ajax: {
          url: $this.attr('urlToGet')
          // data: data,
        }
      },
      position: {
        at: 'right middle',
        my: 'left top',
        adjust: {
          screen: 'flip'
        }
      },
      hide: {
        fixed: true,
        when: 'mouseout'
      },
      show: {
        solo: true,
        delay: 500,
        ready: true
      },
      style: {
        classes: 'ui-tooltip-light InfoCardTip',
        widget: true,
        tip: {
          corner: true,
          width: 15,
          height: 15
        }
      }
    });
    $this.data("toolTipAttached", true);
  }
});
</code>```

There are 2 different versions of this for 2 different classes, one gets a single "shift" one gets the user s for a bunch of shifts. as with other things.  once the function itself runs quick,  the ajax is fast, the v2ReLoadScheduledActivitySection runs in about 50 ms. nothing interesting in there. :

```<code>$('div.GetShiftUserArrow').die('click');
$('div.GetShiftUserArrow').live('click', function () {
  var listIsVisible = $(this).attr('listIsVisible');
  var holder = $('#' + $(this).attr('listHolder'));
  var activityHolder = $('#TopLevel{0}'.format($(this).attr('activityShiftId')));

  if (listIsVisible == -1) {
    v2ReLoadScheduledActivitySection($(this), 1);
  } else {
    holder.empty().toggle('hide');
    $(this).removeClass('GetShiftUserArrowOpen');
    $(this).attr('listIsVisible', listIsVisible * -1);
  }
});
</code>```

Here's a bit of the HTML. this is the
 for a day... the main list has one of these for every day of the year (or whatever range they pick).  There could be any number of sub li's in that list, but it tends to be between 1-10.

```<code><li class="EntityRow" style="font-weight:normal;">
 <div class="TopLevelRow" sectiondate="1/21/2011 12:00:00 AM">
  <div class="ScheduleDayHeader OnlyFloatLeftInIE7" style="width:100%;margin-bottom:0px;font-weight:normal;">
   <div class="Buttons OnlyFloatLeftInIE7" style="padding-top:0px; padding-bottom:0px;margin-top:0px;margin-bottom:0px;">
    <div class="GetDayUserArrow OnlyFloatLeftInIE7" listisvisible="-1" sectiondate="1/21/2011 12:00:00 AM" url="/This/IsNot/TheReal/Url"></div>
   </div><span class="CategorizedNameHolder OnlyFloatLeftInIE7" style="display:inline-block; width:380px;padding-bottom:2px;">Friday, January 21, 2011</span> <span class="TimeHolderSpan">Start</span> <span class="TimeHolderSpan">End</span> <span class="StatusIcons">Status</span> <span class="SkinnyColumn GlossaryMe" tooltip="A Number">Mn</span> <span class="SkinnyColumn GlossaryMe" tooltip="A Number">Mx</span> <span class="SkinnyColumn GlossaryMe" tooltip="A Number">BU</span> <span class=
   "SkinnyColumn GlossaryMe" tooltip="A Number">Av</span> <span class="SkinnyColumn GlossaryMe" tooltip="Assigned">As</span> <span class="SkinnyColumn GlossaryMe" tooltip="A Number">Co</span>
  </div>

  <div class="ShiftListHolder" sectiondate="1/21/2011 12:00:00 AM">
   <ul class="ScheduledActivitiesForDayList EntityList FancyList SubList">
    <li class="EntityRow" activityshiftid="4645" id="ListItemFor4645">
     <div class="BlueOnHover ScheduleShiftHeader" style="width:100%;">
      <div class="Buttons OnlyFloatLeftInIE7" style="padding-top:0px; padding-bottom:0px;margin-top:0px;margin-bottom:0px;">
       <div class="GetShiftUserArrow OnlyFloatLeftInIE7" listisvisible="-1" activityshiftid="4645" url="/Some/Url=4645" sectiondate="1/21/2011 12:00:00 AM"></div>
      </div><span class="CategorizedNameHolder OnlyFloatLeftInIE7" style="display:inline-block; width:350px;padding-bottom:2px;"><span class="AssignLink" activityshiftid="4645">SomeText</span></span> <span class="TimeHolderSpan">9:00 AM</span> <span class="TimeHolderSpan">12:30 PM</span>

      <div class="StatusIcons OnlyFloatLeftInIE7">
       <div class='TipMe LegendMe ClassToPickTheIcon' tooltip='Min # scheduled' legendgroupid='5'>
        <span class='NoDisplay'>3</span>
       </div>

       <div class='TipMe LegendMe OtherClassToPickTheIcon' tooltip='Unlocked' legendgroupid='5'>
        <span class='NoDisplay'>2</span>
       </div>

       <div class='TipMe LegendMe AnotherClassToPickTheIcon' tooltip='Do not auto assign' legendgroupid='5'>
        <span class='NoDisplay'>1</span>
       </div>

       <div class='TipMe LegendMe ClassToPickTheIconAgain' tooltip='Do not autolock' legendgroupid='5'>
        <span class='NoDisplay'>1</span>
       </div>
      </div><span class="OnlyFloatLeftInIE7"><span class="SkinnyColumn TipMe ContentToolTip" tooltip="A Number">1</span> <span class="SkinnyColumn TipMe ContentToolTip" tooltip="A Number">--</span> <span class="SkinnyColumn TipMe ContentToolTip" tooltip="A Number">0</span> <span class="SkinnyColumn TipMe ContentToolTip" tooltip="A Number">0</span> <span class="SkinnyColumn TipMe ContentToolTip" tooltip="Assigned">2</span> <span class="SkinnyColumn TipMe ContentToolTip" tooltip=
      "A Number">0</span></span>
     </div>

     <div class="UserListHoder" id="UserListHolder4645" activityshiftid="4645"></div>
    </li>

    <li class="EntityRow" activityshiftid="4129" id="ListItemFor4129">
     <div class="BlueOnHover ScheduleShiftHeader" style="width:100%;">
      <div class="Buttons OnlyFloatLeftInIE7" style="padding-top:0px; padding-bottom:0px;margin-top:0px;margin-bottom:0px;">
       <div class="GetShiftUserArrow OnlyFloatLeftInIE7" listisvisible="-1" activityshiftid="4129" url="/Some/Url=4129" sectiondate="1/21/2011 12:00:00 AM"></div>
      </div><span class="CategorizedNameHolder OnlyFloatLeftInIE7" style="display:inline-block; width:350px;padding-bottom:2px;"><span class="AssignLink" activityshiftid="4129">Blah Bla blah</span></span> <span class="TimeHolderSpan">9:00 AM</span> <span class="TimeHolderSpan">5:00 PM</span>

      <div class="StatusIcons OnlyFloatLeftInIE7">
       <div class='TipMe LegendMe ClassToPickTheIcon' tooltip='Min # scheduled' legendgroupid='5'>
        <span class='NoDisplay'>3</span>
       </div>

       <div class='TipMe LegendMe OtherClassToPickTheIcon' tooltip='Unlocked' legendgroupid='5'>
        <span class='NoDisplay'>2</span>
       </div>

       <div class='TipMe LegendMe AnotherClassToPickTheIcon' tooltip='Do not auto assign' legendgroupid='5'>
        <span class='NoDisplay'>1</span>
       </div>

       <div class='TipMe LegendMe OtherClassForIcon' tooltip='on availabilities' legendgroupid='5'>
        <span class='NoDisplay'>2</span>
       </div>
      </div><span class="OnlyFloatLeftInIE7"><span class="SkinnyColumn TipMe ContentToolTip" tooltip="A Number">1</span> <span class="SkinnyColumn TipMe ContentToolTip" tooltip="A Number">5</span> <span class="SkinnyColumn TipMe ContentToolTip" tooltip="A Number">0</span> <span class="SkinnyColumn TipMe ContentToolTip" tooltip="A Number">0</span> <span class="SkinnyColumn TipMe ContentToolTip" tooltip="Assigned">5</span> <span class="SkinnyColumn TipMe ContentToolTip" tooltip=
      "A Number">0</span></span>
     </div>

     <div class="UserListHoder" id="UserListHolder4129" activityshiftid="4129"></div>
    </li>

    <li class="EntityRow" activityshiftid="3534" id="ListItemFor3534">
     <div class="BlueOnHover ScheduleShiftHeader" style="width:100%;">
      <div class="Buttons OnlyFloatLeftInIE7" style="padding-top:0px; padding-bottom:0px;margin-top:0px;margin-bottom:0px;">
       <div class="GetShiftUserArrow OnlyFloatLeftInIE7" listisvisible="-1" activityshiftid="3534" url="/Some/Url=3534" sectiondate="1/21/2011 12:00:00 AM"></div>
      </div><span class="CategorizedNameHolder OnlyFloatLeftInIE7" style="display:inline-block; width:350px;padding-bottom:2px;"><span class="AssignLink" activityshiftid="3534">even more</span></span> <span class="TimeHolderSpan">1:00 PM</span> <span class="TimeHolderSpan">4:30 PM</span>

      <div class="StatusIcons OnlyFloatLeftInIE7">
       <div class='TipMe LegendMe SchedulingFullyA NumberIcon' tooltip='Min # A Number' legendgroupid='5'>
        <span class='NoDisplay'>4</span>
       </div>

       <div class='TipMe LegendMe LockedIcon' tooltip='Locked' legendgroupid='5'>
        <span class='NoDisplay'>1</span>
       </div>

       <div class='TipMe LegendMe ClassToPickTheIconAgain' tooltip='Auto assign' legendgroupid='5'>
        <span class='NoDisplay'>2</span>
       </div>

       <div class='TipMe LegendMe OtherClassForIcon' tooltip='on assignments' legendgroupid='5'>
        <span class='NoDisplay'>3</span>
       </div>
      </div><span class="OnlyFloatLeftInIE7"><span class="SkinnyColumn TipMe ContentToolTip" tooltip="A Number">1</span> <span class="SkinnyColumn TipMe ContentToolTip" tooltip="A Number">5</span> <span class="SkinnyColumn TipMe ContentToolTip" tooltip="A Number">0</span> <span class="SkinnyColumn TipMe ContentToolTip" tooltip="A Number">0</span> <span class="SkinnyColumn TipMe ContentToolTip" tooltip="Assigned">7</span> <span class="SkinnyColumn TipMe ContentToolTip" tooltip=
      "A Number">3</span></span>
     </div>

     <div class="UserListHoder" id="UserListHolder3534" activityshiftid="3534"></div>
    </li>
   </ul>
  </div>
 </div>
</li>

</code>```

anything with TipMe, or GlossaryMe brings up a qtip tooltip.

like this:

```<code> $(".TipMe").live("mouseover", function () {
  var $this = $(this);
  $this.removeAttr('title');
  $this.removeAttr('alt');

  if (!$this.data("toolTipAttached")) {

    $this.qtip({
      show: {
        ready: true,
        solo: true,
        delay: 500
      },
      style: {
        classes: 'ui-tooltip-light InfoCardTip',
        widget: true
      },
      content: $this.attr('tooltip'),
      position: {
        at: 'bottomRight',
        my: 'topleft',
        adjust: {
          screen: 'flip',
          x: 0,
          y: 0
        }
      },
      hide: {
        fixed: true,
        inactive: 1000
      }
    });
    $this.data("toolTipAttached", true);
    //    $this.trigger("mouseover");
  }
});
</code>```

Something tells me it might be all my tooltip handlers that are causing the problem...

Let me know if you guys want anything else!

答:
If your javascript uses a lot of memory when run in IE, that could slow things down.  Check memory consumption by looking at the iexplore.exe process in Windows Task Manager.  If it turns out IE is using a lot of memory, try to optimize your code.  Particularly look for:

Closures that may not be going out of scope - especially nested closures

Circular references between the dom and your script

Excessive unnecessary persistent dom references within your script

Another thing you might try is to use document.querySelector to find elements without ids in IE8/IE9/chrome/firefox (or element.querySelector).  IE7 users will have to suffer, but that's what you get for not upgrading!  ;-)

ContentLicense: CC BY-SA 2.5

Body:
I'm working on a site that has a page that can potentially become very long.  It can have in theory 1000+ rows of data in it.  Then these rows could each have sub-rows.

I'm currently using a list / sublist structure to represent the data because it's difficult to visualize subsets in tables.  the subset data is in a table though.

The Problem is this:  In IE.   my hovering over the row styles,  tooltips and other javascripts are taking upwards of 5 seconds to fire!   The page hangs like crazy and is pretty much unuseable.  In FF, Chrome, and Safari it works just fine.

I don't need a whole bunch of stats saying IE is slow. i know it is. what i need is some suggestions / theories/ ideas on how to combat the slowness!

Some of the ideas i've had so far:
-some kind of paging mechanism.   But that gets tricky b/c 1.  It's a list not a table, and 2.  it's got sub sub lists and sub tables for those sub lists.   so we'd need to somehow page based on the top level i think.  because we don't want to split the data up at all.    I guess that might be feasible...

-some kind of mechanism that holds the content in a javascript array or object or soomething and doesn't add it to the dom until it's been scrolled to.   and takes it away when you scroll past it.  in theory this would be cool. but i think it would be horrible to impliment.

-something else entirely?

Thanks in Advance for any ideas!  I'm probably going to try and put a bounty on this as soon as i'm able to help inspire you ;)

EDIT:

OH MY!  I think i may have found part of the problem using dyna trace!  thanks Pointy for reminding me about this tool. i had forgotten about out.   the click event of one of my buttons seems to be firing an insane amount.  like 2000 times and count.  something is clicking it automatically or something crazy like that.   weird thing is, i don't have any javascripts that trigger that button click!  EDIT:  This doesn't seem to be an issue anymore.

EDIT:

Also: i don't think it is the complexity of my markup that is affecting the responsiveness of my scripts(i know if i could use just id selectors it would be best, but i've optimized my selectors and qtips as much as possible (with help from s.o. in the past).  i have a button that is just on the page, not nested in anything,  that the click handler takes 4 or 5 seconds to register.  It's not that the click action takes a long time, it's just slow to notice that it's been clicked.

EDIT: i had 5 spans that were each nested in a span unnecessarily,  i un-nested those and it seems to have cut the slowness in about 1/2!!    (these 5 spans were repeated in every row)

EDIT:   Here's some of the relevant scripts:

The Main Button Handler:

$('#FilterScheduledShifts').click(function () {
  var categoryId = $('#CategoryId').val();
  var activityId = $('#ActivityId').val();
  var shiftStatusFilters = GetShiftStatusFilterIds();
  var dayOfWeekFilters = GetDayOfWeekFilters();
  var startDateFilter = GetStartDateFilter();
  var endDateFilter = GetStartEndFilter();
  var dataToPost = {
    categoryId: categoryId,
    activityId: activityId,
    statuses: shiftStatusFilters,
    daysOfWeek: dayOfWeekFilters,
    startDate: startDateFilter,
    endDate: endDateFilter
  };
  var url = $('#UrlToFilter').val();
  $('#ListHolder').html("<%=web.loading %>");
  $.ajax({
    url: url,
    data: dataToPost,
    type: 'POST',
    success: function (data) {
      document.getElementById('ScheduledActivityShiftListHolder').innerHTML = data;
    },
    error: function () {
      v2ErrorNotice(v2Text.shared.genericAjaxErrorMessage);
    }
  });
});

The Get...FIlter functions are very simple functions that run in a few milliseconds... nothing interesting or noteworthy happening in there.

this bit attaches some of the behaviour that is very slow:
in other pages they react nice and quick, on this page... 2-3 seconds.

$('span.infoCard').die();
$('span.infoCard').live("mouseover", function () {

  var $this = $(this);
  if (!$this.data("toolTipAttached")) {

    var title = '';

    if ($this.attr('infoCardTitle') != "") {
      title = $this.attr('infoCardTitle');
    } else {
      title = $this.html();
    }

    $this.qtip({
      content: {
        text: "loading",
        title: title,
        ajax: {
          url: $this.attr('urlToGet')
          // data: data,
        }
      },
      position: {
        at: 'right middle',
        my: 'left top',
        adjust: {
          screen: 'flip'
        }
      },
      hide: {
        fixed: true,
        when: 'mouseout'
      },
      show: {
        solo: true,
        delay: 500,
        ready: true
      },
      style: {
        classes: 'ui-tooltip-light InfoCardTip',
        widget: true,
        tip: {
          corner: true,
          width: 15,
          height: 15
        }
      }
    });
    $this.data("toolTipAttached", true);
  }
});

There are 2 different versions of this for 2 different classes, one gets a single "shift" one gets the user s for a bunch of shifts. as with other things.  once the function itself runs quick,  the ajax is fast, the v2ReLoadScheduledActivitySection runs in about 50 ms. nothing interesting in there. :

$('div.GetShiftUserArrow').die('click');
$('div.GetShiftUserArrow').live('click', function () {
  var listIsVisible = $(this).attr('listIsVisible');
  var holder = $('#' + $(this).attr('listHolder'));
  var activityHolder = $('#TopLevel{0}'.format($(this).attr('activityShiftId')));

  if (listIsVisible == -1) {
    v2ReLoadScheduledActivitySection($(this), 1);
  } else {
    holder.empty().toggle('hide');
    $(this).removeClass('GetShiftUserArrowOpen');
    $(this).attr('listIsVisible', listIsVisible * -1);
  }
});

Here's a bit of the HTML. this is the
 for a day... the main list has one of these for every day of the year (or whatever range they pick).  There could be any number of sub li's in that list, but it tends to be between 1-10.

Friday, January 21, 2011 Start End Status Mn Mx BU Av As Co

SomeText 9:00 AM 12:30 PM

        3

        2

        1

        1

1 -- 0 0 2 0

Blah Bla blah 9:00 AM 5:00 PM

        3

        2

        1

        2

1 5 0 0 5 0

even more 1:00 PM 4:30 PM

        4

        1

        2

        3

1 5 0 0 7 3

anything with TipMe, or GlossaryMe brings up a qtip tooltip.

like this:

 $(".TipMe").live("mouseover", function () {
  var $this = $(this);
  $this.removeAttr('title');
  $this.removeAttr('alt');

  if (!$this.data("toolTipAttached")) {

    $this.qtip({
      show: {
        ready: true,
        solo: true,
        delay: 500
      },
      style: {
        classes: 'ui-tooltip-light InfoCardTip',
        widget: true
      },
      content: $this.attr('tooltip'),
      position: {
        at: 'bottomRight',
        my: 'topleft',
        adjust: {
          screen: 'flip',
          x: 0,
          y: 0
        }
      },
      hide: {
        fixed: true,
        inactive: 1000
      }
    });
    $this.data("toolTipAttached", true);
    //    $this.trigger("mouseover");
  }
});

Something tells me it might be all my tooltip handlers that are causing the problem...

Let me know if you guys want anything else!


问:
How to make mouseover functionality permanent
I want to make a force graph with permanently visible text on the nodes and text on the links.

This snippet provides labels on the nodes.

The 2nd snippet from an answer to Show tool-tip on links of force directed graph in d3js provides mouseover labels on links and nodes.

I'm currently trying to extend the second to make the mouseover node labels permanent.

var width = 400;
var height = 125;
var margin = 20;
var pad = margin / 2;

var graph = {  "nodes":[ { "name": "A"}, { "name": "B"}] };
drawGraph(graph);

function drawGraph(graph) {
  var svg = d3.select("#force").append("svg")
    .attr("width", width)
    .attr("height", height);

  // create an area within svg for plotting graph
  var plot = svg.append("g")
    .attr("id", "plot")
    .attr("transform", "translate(" + pad + ", " + pad + ")");

  var layout = d3.layout.force()
    .size([width - margin, height - margin])
    .charge(-120)
    .nodes(graph.nodes)
    .start();

  drawNodes(graph.nodes);

  // add ability to drag and update layout
  d3.selectAll(".node").call(layout.drag);

  layout.on("tick", function() {
    d3.selectAll(".node")
      .attr("cx", d =>  { return d.x; })
      .attr("cy", d =>  { return d.y; });

  });
}

// Draws nodes on plot
function drawNodes(nodes) {

  d3.select("#plot").selectAll(".node")
    .data(nodes)
    .enter()
    .append("circle")
    .attr("class", "node")
    .attr("id", (d, i) => { return d.name;  })
    .attr("cx", (d, i) => { return d.x;  })
    .attr("cy", (d, i) => { return d.y;  })
    .attr("r",  4)
    .style("fill", "#EE77b4")
    .on("mouseover", function(d, i) {

      var x = d3.mouse(this)[0];
      var y = d3.mouse(this)[1];
      var tooltip = d3.select("#plot")
        .append("text")
        .text(d.name)
        .attr("x", x)
        .attr("y", y)
        .attr("id", "tooltip");

    })
    .on("mouseout", function(d, i) {
      d3.select("#tooltip").remove();
    });
}```
<pre class="snippet-code-css lang-css prettyprint-override"><code>body {
  font-family: 'Source Sans Pro', sans-serif;
  font-weight: 300;
}
b {
  font-weight: 900;
}
.outline {
  fill: none;
  stroke: #888888;
  stroke-width: 1px;
}
#tooltip {
  font-size: 10pt;
  font-weight: 900;
  fill: #000000;
  stroke: #ffffff;
  stroke-width: 0.25px;
}
.node {
  stroke: #ffffff;
  stroke-weight: 1px;
}
.highlight {
  stroke: red;
  stroke-weight: 4px;
  stroke-opacity: 1.0;
}</code>```

```
</div>
</div>
</p>

<p>I've tried replacing the mouseover function with:</p>

```.each( function(d, i) {
      var x = d.x; //d3.mouse(this)[0];
      var y = d.y; //d3.mouse(this)[1];
      var tooltip = d3.select("#plot")
        .append("text")
        .text(d.name)
        .attr("x", x)
    .attr("y", y)
    .attr("id", "tooltip");

    })
```

<p>but now the labels don't move so I added</p>

```d3.selectAll("text").attr( "x", d => { return d.x; })
                    .attr( "y", d => { return d.y; });
```

in layout.on("tick", function() ...

But now it's all in one place doesn't move and I get TypeError: d is undefined

答:
Rewrite your code this way (pay attention on the comments):

```<code>  layout.on("tick", function() {
    tooltips // here we set new position for tooltips on every tick
      .attr("x", (d, i) => { return d.x;  })
      .attr("y", (d, i) => { return d.y;  });

    d3.selectAll(".node")
      .attr("cx", d =>  { return d.x; })
      .attr("cy", d =>  { return d.y; });

  });

...

function drawNodes(nodes) {
  tooltips = d3.select("#plot").selectAll(".node")
    .data(nodes)
    .enter()
    .append("circle")
    .attr("class", "node")
    .attr("id", (d, i) => { return d.name;  })
    .attr("cx", (d, i) => { return d.x;  })
    .attr("cy", (d, i) => { return d.y;  })
    .attr("r",  4)
    .style("fill", "#EE77b4")
    .select(function() { return this.parentNode }) // returns to parent node
    .append('text') // append svg-text elements for tooltip
    .data(nodes)
    .text(function(d) { return d.name; }) // set text
    .attr("x", (d, i) => { return d.x;  }) // set initial x position
    .attr("y", (d, i) => { return d.y;  }) // set initial y position
    .attr("id", function(d,i) { return "tooltip-" + i; }) // set unique id
    .attr("class", "d3-tooltip");
}
</code>```

Working demo:

var width = 400;
var height = 125;
var margin = 20;
var pad = margin / 2;
var tooltips = null;

var graph = {  "nodes":[ { "name": "A"}, { "name": "B"}] };
drawGraph(graph);

function drawGraph(graph) {
  var svg = d3.select("#force").append("svg")
    .attr("width", width)
    .attr("height", height);

  // create an area within svg for plotting graph
  var plot = svg.append("g")
    .attr("id", "plot")
    .attr("transform", "translate(" + pad + ", " + pad + ")");

  var layout = d3.layout.force()
    .size([width - margin, height - margin])
    .charge(-120)
    .nodes(graph.nodes)
    .start();

  drawNodes(graph.nodes);

  // add ability to drag and update layout
  d3.selectAll(".node").call(layout.drag);

  layout.on("tick", function() {
    tooltips
      .attr("x", (d, i) => { return d.x;  })
      .attr("y", (d, i) => { return d.y;  });

    d3.selectAll(".node")
      .attr("cx", d =>  { return d.x; })
      .attr("cy", d =>  { return d.y; });

  });
}

// Draws nodes on plot
function drawNodes(nodes) {
  tooltips = d3.select("#plot").selectAll(".node")
    .data(nodes)
    .enter()
    .append("circle")
    .attr("class", "node")
    .attr("id", (d, i) => { return d.name;  })
    .attr("cx", (d, i) => { return d.x;  })
    .attr("cy", (d, i) => { return d.y;  })
    .attr("r",  4)
    .style("fill", "#EE77b4")
    .select(function() { return this.parentNode })
    .append('text')
    .data(nodes)
    .text(function(d) { return d.name; })
    .attr("x", (d, i) => { return d.x;  })
    .attr("y", (d, i) => { return d.y;  })
    .attr("class", "d3-tooltip")
    .attr("id", function(d,i) { return "tooltip-" + i; });
}```
<pre class="snippet-code-css lang-css prettyprint-override"><code>body {
  font-family: 'Source Sans Pro', sans-serif;
  font-weight: 300;
}
b {
  font-weight: 900;
}
.outline {
  fill: none;
  stroke: #888888;
  stroke-width: 1px;
}
.d3-tooltip {
  font-size: 20pt;
  font-family: 'Comic Sans MS';
  font-weight: 900;
  fill: #000000;
  stroke: #ffffff;
  stroke-width: 0.25px;
}
.node {
  stroke: #ffffff;
  stroke-weight: 1px;
}
.highlight {
  stroke: red;
  stroke-weight: 4px;
  stroke-opacity: 1.0;
}</code>```

```

Body:
I want to make a force graph with permanently visible text on the nodes and text on the links.

This snippet provides labels on the nodes.

The 2nd snippet from an answer to Show tool-tip on links of force directed graph in d3js provides mouseover labels on links and nodes.

I'm currently trying to extend the second to make the mouseover node labels permanent.

var width = 400;
var height = 125;
var margin = 20;
var pad = margin / 2;

var graph = {  "nodes":[ { "name": "A"}, { "name": "B"}] };
drawGraph(graph);

function drawGraph(graph) {
  var svg = d3.select("#force").append("svg")
    .attr("width", width)
    .attr("height", height);

  // create an area within svg for plotting graph
  var plot = svg.append("g")
    .attr("id", "plot")
    .attr("transform", "translate(" + pad + ", " + pad + ")");

  var layout = d3.layout.force()
    .size([width - margin, height - margin])
    .charge(-120)
    .nodes(graph.nodes)
    .start();

  drawNodes(graph.nodes);

  // add ability to drag and update layout
  d3.selectAll(".node").call(layout.drag);

  layout.on("tick", function() {
    d3.selectAll(".node")
      .attr("cx", d =>  { return d.x; })
      .attr("cy", d =>  { return d.y; });

  });
}

// Draws nodes on plot
function drawNodes(nodes) {

  d3.select("#plot").selectAll(".node")
    .data(nodes)
    .enter()
    .append("circle")
    .attr("class", "node")
    .attr("id", (d, i) => { return d.name;  })
    .attr("cx", (d, i) => { return d.x;  })
    .attr("cy", (d, i) => { return d.y;  })
    .attr("r",  4)
    .style("fill", "#EE77b4")
    .on("mouseover", function(d, i) {

      var x = d3.mouse(this)[0];
      var y = d3.mouse(this)[1];
      var tooltip = d3.select("#plot")
        .append("text")
        .text(d.name)
        .attr("x", x)
        .attr("y", y)
        .attr("id", "tooltip");

    })
    .on("mouseout", function(d, i) {
      d3.select("#tooltip").remove();
    });
}

body {
  font-family: 'Source Sans Pro', sans-serif;
  font-weight: 300;
}
b {
  font-weight: 900;
}
.outline {
  fill: none;
  stroke: #888888;
  stroke-width: 1px;
}
#tooltip {
  font-size: 10pt;
  font-weight: 900;
  fill: #000000;
  stroke: #ffffff;
  stroke-width: 0.25px;
}
.node {
  stroke: #ffffff;
  stroke-weight: 1px;
}
.highlight {
  stroke: red;
  stroke-weight: 4px;
  stroke-opacity: 1.0;
}

I've tried replacing the mouseover function with:

.each( function(d, i) {
      var x = d.x; //d3.mouse(this)[0];
      var y = d.y; //d3.mouse(this)[1];
      var tooltip = d3.select("#plot")
        .append("text")
        .text(d.name)
        .attr("x", x)
    .attr("y", y)
    .attr("id", "tooltip");

    })

but now the labels don't move so I added

d3.selectAll("text").attr( "x", d => { return d.x; })
                    .attr( "y", d => { return d.y; });

in layout.on("tick", function() ...

But now it's all in one place doesn't move and I get TypeError: d is undefined

Body:
Rewrite your code this way (pay attention on the comments):

  layout.on("tick", function() {
    tooltips // here we set new position for tooltips on every tick
      .attr("x", (d, i) => { return d.x;  })
      .attr("y", (d, i) => { return d.y;  });

    d3.selectAll(".node")
      .attr("cx", d =>  { return d.x; })
      .attr("cy", d =>  { return d.y; });

  });

...

function drawNodes(nodes) {
  tooltips = d3.select("#plot").selectAll(".node")
    .data(nodes)
    .enter()
    .append("circle")
    .attr("class", "node")
    .attr("id", (d, i) => { return d.name;  })
    .attr("cx", (d, i) => { return d.x;  })
    .attr("cy", (d, i) => { return d.y;  })
    .attr("r",  4)
    .style("fill", "#EE77b4")
    .select(function() { return this.parentNode }) // returns to parent node
    .append('text') // append svg-text elements for tooltip
    .data(nodes)
    .text(function(d) { return d.name; }) // set text
    .attr("x", (d, i) => { return d.x;  }) // set initial x position
    .attr("y", (d, i) => { return d.y;  }) // set initial y position
    .attr("id", function(d,i) { return "tooltip-" + i; }) // set unique id
    .attr("class", "d3-tooltip");
}

Working demo:

var width = 400;
var height = 125;
var margin = 20;
var pad = margin / 2;
var tooltips = null;

var graph = {  "nodes":[ { "name": "A"}, { "name": "B"}] };
drawGraph(graph);

function drawGraph(graph) {
  var svg = d3.select("#force").append("svg")
    .attr("width", width)
    .attr("height", height);

  // create an area within svg for plotting graph
  var plot = svg.append("g")
    .attr("id", "plot")
    .attr("transform", "translate(" + pad + ", " + pad + ")");

  var layout = d3.layout.force()
    .size([width - margin, height - margin])
    .charge(-120)
    .nodes(graph.nodes)
    .start();

  drawNodes(graph.nodes);

  // add ability to drag and update layout
  d3.selectAll(".node").call(layout.drag);

  layout.on("tick", function() {
    tooltips
      .attr("x", (d, i) => { return d.x;  })
      .attr("y", (d, i) => { return d.y;  });

    d3.selectAll(".node")
      .attr("cx", d =>  { return d.x; })
      .attr("cy", d =>  { return d.y; });

  });
}

// Draws nodes on plot
function drawNodes(nodes) {
  tooltips = d3.select("#plot").selectAll(".node")
    .data(nodes)
    .enter()
    .append("circle")
    .attr("class", "node")
    .attr("id", (d, i) => { return d.name;  })
    .attr("cx", (d, i) => { return d.x;  })
    .attr("cy", (d, i) => { return d.y;  })
    .attr("r",  4)
    .style("fill", "#EE77b4")
    .select(function() { return this.parentNode })
    .append('text')
    .data(nodes)
    .text(function(d) { return d.name; })
    .attr("x", (d, i) => { return d.x;  })
    .attr("y", (d, i) => { return d.y;  })
    .attr("class", "d3-tooltip")
    .attr("id", function(d,i) { return "tooltip-" + i; });
}

body {
  font-family: 'Source Sans Pro', sans-serif;
  font-weight: 300;
}
b {
  font-weight: 900;
}
.outline {
  fill: none;
  stroke: #888888;
  stroke-width: 1px;
}
.d3-tooltip {
  font-size: 20pt;
  font-family: 'Comic Sans MS';
  font-weight: 900;
  fill: #000000;
  stroke: #ffffff;
  stroke-width: 0.25px;
}
.node {
  stroke: #ffffff;
  stroke-weight: 1px;
}
.highlight {
  stroke: red;
  stroke-weight: 4px;
  stroke-opacity: 1.0;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div align="center" id="force"></div>


问:
Curl Not Found Error in RMixpanel
I'm trying to Download Data From Mixpanel by writing a JQL Query. I have used this function

Mixpanel_Data <- mixpanelJQLQuery(MixP, jqlString = JQL_Query )

I'm getting the following error

Error in system(curlCall, intern = TRUE, ignore.stderr = TRUE) :
   'curl' not found

Please help as I can't find anything regarding this online.

答: The function mixpanelJQLQuery() makes a system call curl to download the data. In your case the system is not finding curl. If you're on a linux like OS you can install it by running: sudo apt-get install curl in the shell prompt. Otherwise you can modify mixpanelJQLQuery() to use wget by replacing curl with wget in the system function.

Title: Curl Not Found Error in RMixpanel


问:
Subdomain on GCP for split domain routing
How can I make a subdomain on google cloud platform for split domain routing? I already have an email provider on my domain so I want to do SDR to connect another email provider. My domain is registered from GoDaddy and then pointed to GCP where is hosted by Bitnami WordPress. </p>

答:
I understand that you want to create a Split Domain Routing using GCP but you should know that Google Cloud is blocking the outbound connections on ports 25, 465, and 587.
So if you want to create an SDN you have to  set up your own email server on an instance using a non-standard ports and create the MX records in your DNS. </p>


问:
Subquery returns more than 1 row. Using SQL select to update a different tables results
I am trying to update a column in the following table 'jobqueue' using the results from a SELECT query performed on the 'mdtinfo' table.

The column I am trying to update is called ignore and I need to set the value to 1 from its default of 0.

```<code>update jobqueue
set jobqueue.`ignore`= '1'
   where (SELECT JobQueue_job_queue_id
    FROM mdtinfo
    WHERE product_name  = 'Example')
</code>```

The above query returns the following error: SQL Error (1242): Subquery returns more than 1 row.

When running the select query on it's own it returns results successfully.

答:
```<code>update jobqueue
set jobqueue.`ignore`= '1'
    where jobqueue.`job_queue_id` IN (SELECT GROUP_CONCAT(JobQueue_job_queue_id)
    FROM mdtinfo
    WHERE product_name  = 'Example' GROUP BY product_name)
</code>```

you should write column name in where condition.

Body:
I am trying to update a column in the following table 'jobqueue' using the results from a SELECT query performed on the 'mdtinfo' table.

The column I am trying to update is called ignore and I need to set the value to 1 from its default of 0.

update jobqueue
set jobqueue.`ignore`= '1'
   where (SELECT JobQueue_job_queue_id
    FROM mdtinfo
    WHERE product_name  = 'Example')

The above query returns the following error: SQL Error (1242): Subquery returns more than 1 row.

When running the select query on it's own it returns results successfully.

Body:
update jobqueue
set jobqueue.`ignore`= '1'
    where jobqueue.`job_queue_id` IN (SELECT GROUP_CONCAT(JobQueue_job_queue_id)
    FROM mdtinfo
    WHERE product_name  = 'Example' GROUP BY product_name)

you should write column name in where condition.


问:
Python get a dict entry containing certain field
I have a nested dict in Python containing YAML structures like

```<code>  - id: left_time
    type: u2
    doc: Time left
</code>```

and I want to obtain pairs like {id: doc}. For this example I want it to be: {"left_time": "Time left"}. The problem is I need to walk through them recursively.

My attempt is

```<code>def get_dict_recursively(search_dict, field):
    fields_found = []

    name = ""

    for key, value in search_dict.items():

        if key == "id":
            name = value

        if key == field:
            fields_found.append({name: value})

        elif isinstance(value, dict):
            results = get_dict_recursively(value, field)
            for result in results:
                fields_found.append({name: result})

        elif isinstance(value, list):
            for item in value:
                if isinstance(item, dict):
                    more_results = get_dict_recursively(item, field)
                    for another_result in more_results:
                        fields_found.append({name: another_result})

    return fields_found
</code>```

calling it like

```<code>get_dict_recursively(dict, "doc")
</code>```

where

```<code>dict = {
  meta:
    id: foo
    title: Foo
  types:
    data:
      seq:
        - id: left_time
          type: u2
          doc: Time left
    gps:
      seq:
        - id: gps_st
          type: b2
        - id: sats
          type: b6
          doc: Number of satellites
}
</code>```

There's a mistake, but I can't find it out.

答:
Let's first state your example data as a dict:

```<code>data = {
    "meta": {
        "id": "foo",
        "title": "Foo"
    },
    "types": {
        "data": {
            "seq": [
                {
                    "id": "left_time",
                    "type": "u2",
                    "doc": "Time left"
                }
            ]
        },
        "gps": {
            "seq": [
                {
                    "id": "gps_st",
                    "type": "b2"
                },
                {
                    "id": "sats",
                    "type": "b6",
                    "doc": "Number of satellites"
                }
            ]
        }
    }
}
</code>```

Next, we can simplify your recursive function to look like this:

```<code>def extract_docs(data):
    result = []
    if isinstance(data, list):
        for d in data:
            result += extract_docs(d)
    elif isinstance(data, dict):
        if "id" in data and "doc" in data:
            result.append((data["id"], data["doc"]))
        else:
            for d in data.values():
                result += extract_docs(d)
    return result
</code>```

With this you get

```<code>>>> dict(extract_docs(data))
{'sats': 'Number of satellites', 'left_time': 'Time left'}
</code>```

Body:
I have a nested dict in Python containing YAML structures like

  - id: left_time
    type: u2
    doc: Time left

and I want to obtain pairs like {id: doc}. For this example I want it to be: {"left_time": "Time left"}. The problem is I need to walk through them recursively.

My attempt is

def get_dict_recursively(search_dict, field):
    fields_found = []

    name = ""

    for key, value in search_dict.items():

        if key == "id":
            name = value

        if key == field:
            fields_found.append({name: value})

        elif isinstance(value, dict):
            results = get_dict_recursively(value, field)
            for result in results:
                fields_found.append({name: result})

        elif isinstance(value, list):
            for item in value:
                if isinstance(item, dict):
                    more_results = get_dict_recursively(item, field)
                    for another_result in more_results:
                        fields_found.append({name: another_result})

    return fields_found

calling it like

get_dict_recursively(dict, "doc")

where

dict = {
  meta:
    id: foo
    title: Foo
  types:
    data:
      seq:
        - id: left_time
          type: u2
          doc: Time left
    gps:
      seq:
        - id: gps_st
          type: b2
        - id: sats
          type: b6
          doc: Number of satellites
}

There's a mistake, but I can't find it out.

Body:
Let's first state your example data as a dict:

data = {
    "meta": {
        "id": "foo",
        "title": "Foo"
    },
    "types": {
        "data": {
            "seq": [
                {
                    "id": "left_time",
                    "type": "u2",
                    "doc": "Time left"
                }
            ]
        },
        "gps": {
            "seq": [
                {
                    "id": "gps_st",
                    "type": "b2"
                },
                {
                    "id": "sats",
                    "type": "b6",
                    "doc": "Number of satellites"
                }
            ]
        }
    }
}

Next, we can simplify your recursive function to look like this:

def extract_docs(data):
    result = []
    if isinstance(data, list):
        for d in data:
            result += extract_docs(d)
    elif isinstance(data, dict):
        if "id" in data and "doc" in data:
            result.append((data["id"], data["doc"]))
        else:
            for d in data.values():
                result += extract_docs(d)
    return result

With this you get

>>> dict(extract_docs(data))
{'sats': 'Number of satellites', 'left_time': 'Time left'}


问:
Angularjs ui-router resolve does not wait for all promises
Currently, I'm having trouble with waiting for my promises to pass to resolve.
I understand that it's because it is an async call so the resolve doesn't wait for all of the promises, and just passes in part of my data to resolve.

I've tried searching lot of forums but i can't seem to get it to work.

so here is my home page.

```<code>angular.module('app')
    .component('home', {
        templateUrl: 'Content/app/components/home.html',
        bindings: {},
        controller: ['$http', '$state', 'test',
            function ($http, $state, test) {
                var vm = this;
                vm.userName;

                vm.searchReddit = function () {
                    $http.get('https://www.reddit.com/user/' + vm.userName + '/about.json')
                        .then(function (response) {
                            vm.accountData = response.data.data;
                            vm.accountData.total_karma = vm.accountData.comment_karma + vm.accountData.link_karma;
                            $state.go('redditAnalyzer', { name: vm.userName });
                        });
                }
            }
        ]
    });
</code>```

Once i type in my username, it changes state.
and in my app.js i have

```<code>angular.module('app', ['ui.router', 'chart.js'])
    .config(['$stateProvider', '$urlRouterProvider', function ($stateProvider, $urlRouterProvider) {
        $urlRouterProvider.otherwise('/');
        $stateProvider
            .state('redditAnalyzer', {
                url: '/analyze/:name',
                component: 'redditAnalyzer',
                resolve: {
                    resolve:
                    ['test', '$stateParams', function (test, $stateParams) {
                        var data = test.getAnalysisData($stateParams.name);
                        return data;
                    }
                    ]
                }
            })
            .state('home', {
                url: '/',
                component: 'home'
            });
    }]);
</code>```

I'm calling the function test.getAnalysisData to get the data.

and in my test.js I have

```<code>angular.module('app')
    .factory('test', ['$http', '$state', '$q', function ($http, $state, $q) {
        var vm = this;

        vm.accountData = {};
        vm.after = '';
        vm.bestComment = {};
        vm.bestComment.karma = 0;
        vm.userName;
        vm.bestComment.date = '';
        vm.subreddit = {};
        vm.myChart;

        vm.getAnalysisData = function (redditUser) {
            vm.userName = redditUser;
            vm.resetData(redditUser);
            vm.getAccountInfo(redditUser);
            vm.getAllComments(redditUser);
            return {
                accountData: vm.accountData,
                bestComment: vm.bestComment,
                userName: vm.userName,
                subreddit: vm.subreddit,
                myChart: vm.myChart
            };
        }

        vm.resetData = function (user) {
            vm.accountData = {};
            vm.after = '';
            vm.bestComment = {};
            vm.bestComment.karma = -(Math.pow(2, 53) - 1);
            vm.userName = user;
            vm.date = '';
            vm.subreddit = [];
            vm.topThreeSub = [];
        }

        vm.getAccountInfo = function (user) {
            $http.get('https://www.reddit.com/user/' + user + '/about.json')
                .then(function (response) {
                    vm.accountData = response.data.data;
                    vm.accountData.total_karma = vm.accountData.comment_karma + vm.accountData.link_karma;
                    console.log("I got the account info!");
                });
        }
        vm.getAllComments = function (user) {
            $http.get('https://www.reddit.com/user/' + user + '/comments.json' + vm.after)
                .then(
                function (response) {
                    console.log("I got the comment info!");
                    tempResponse = response;
                    var data = response.data.data
                    vm.after = '?after=' + data.after;
                    for (i = 0; i < data.children.length; i++) {
                        if (vm.bestComment.karma < parseInt(data.children[i].data.score)) {
                            vm.bestComment.karma = parseInt(data.children[i].data.score);
                            vm.bestComment.comment = data.children[i].data.body;
                            vm.bestComment.date = (new Date(data.children[i].data.created * 1000)).toString();
                        }
                        var tempSub = data.children[i].data.subreddit;
                        if (vm.subreddit[tempSub] === undefined) {
                            vm.subreddit[tempSub] = 1;
                        }
                        else {
                            vm.subreddit[tempSub]++;
                        }
                    }
                    if (response.data.data.after != null) {
                        vm.getAllComments(user);
                    }
                }, function (error) {
                    console.log(error);
                    throw error;
                })
                .catch(function (error) { });
        }
        return {
            resolve: vm.resolve,
            hello: vm.hello,
            getAnalysisData: vm.getAnalysisData
        }
    }]);
</code>```

I'm recursively calling the function vm.getAllComments because how it works is vm.getAllComments will get first 25 comments of the account, and then from part of the info from response, I can get the next 25 comments in the account.

and finally, in my redditanalyzer file, I have

```<code>angular.module('app')
    .component('redditAnalyzer', {
        templateUrl: 'Content/app/components/redditAnalyzer.html',
        bindings: {
            resolve: '<'
        },
        controller: ['$http', 'test',
            function ($http, test) {
                var vm = this;
                vm.accountData = {};
                vm.bestComment = {};
                vm.bestComment.karma = 0;
                vm.userName;
                vm.bestComment.date = '';
                vm.subreddit = {};
                vm.myChart;

                vm.$onInit = function () {
                    console.log("this is the resolve", vm.resolve);
                    //vm.accountData = resolve.accountData;
                    //vm.bestComment = resolve.bestComment;
                    //vm.myChart = resolve.myChart;
                    //vm.subreddit = resolve.subreddit;
                    //vm.userName = resolve.userName;
                }

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

And you can see the problem in my console.

```<code>this is the resolve {accountData: {…}, bestComment: {…}, userName: "spez", subreddit: Array(0), myChart: undefined}accountData: {}bestComment: {karma: 22200, comment: "Reddit search might work by then.", date: "Thu Oct 27 2016 01:07:22 GMT-0400 (Eastern Daylight Time)"}myChart: undefinedsubreddit: [blog: 10, announcements: 475, modnews: 34, programming: 32, ModSupport: 20, …]userName: "spez"__proto__: Object
test.js:44 I got the account info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
7test.js:51 I got the comment info!
</code>```

It changes the route even before doing the promises.
What should i do to wait for all of my promises?

答:
I additional, what version of ui-router you are using? on the latest '$stateParams' is deprecated and relapsed with $transition$.

Also you don`t need to use this

```<code>url: '/analyze/:name',
</code>```

In UI-Router legacy, a parameter found in the URL path was optional.
  If the parameter was not found in the URL, it would match the empty
  string.

You can replace with:

```<code>url: '/analyze/',
</code>```

and

```<code>params: {
    name: ""
  }
</code>```

You can read migration guid

Body:
Currently, I'm having trouble with waiting for my promises to pass to resolve.
I understand that it's because it is an async call so the resolve doesn't wait for all of the promises, and just passes in part of my data to resolve.

I've tried searching lot of forums but i can't seem to get it to work.

so here is my home page.

angular.module('app')
    .component('home', {
        templateUrl: 'Content/app/components/home.html',
        bindings: {},
        controller: ['$http', '$state', 'test',
            function ($http, $state, test) {
                var vm = this;
                vm.userName;

                vm.searchReddit = function () {
                    $http.get('https://www.reddit.com/user/' + vm.userName + '/about.json')
                        .then(function (response) {
                            vm.accountData = response.data.data;
                            vm.accountData.total_karma = vm.accountData.comment_karma + vm.accountData.link_karma;
                            $state.go('redditAnalyzer', { name: vm.userName });
                        });
                }
            }
        ]
    });

Once i type in my username, it changes state.
and in my app.js i have

angular.module('app', ['ui.router', 'chart.js'])
    .config(['$stateProvider', '$urlRouterProvider', function ($stateProvider, $urlRouterProvider) {
        $urlRouterProvider.otherwise('/');
        $stateProvider
            .state('redditAnalyzer', {
                url: '/analyze/:name',
                component: 'redditAnalyzer',
                resolve: {
                    resolve:
                    ['test', '$stateParams', function (test, $stateParams) {
                        var data = test.getAnalysisData($stateParams.name);
                        return data;
                    }
                    ]
                }
            })
            .state('home', {
                url: '/',
                component: 'home'
            });
    }]);

I'm calling the function test.getAnalysisData to get the data.

and in my test.js I have

angular.module('app')
    .factory('test', ['$http', '$state', '$q', function ($http, $state, $q) {
        var vm = this;

        vm.accountData = {};
        vm.after = '';
        vm.bestComment = {};
        vm.bestComment.karma = 0;
        vm.userName;
        vm.bestComment.date = '';
        vm.subreddit = {};
        vm.myChart;

        vm.getAnalysisData = function (redditUser) {
            vm.userName = redditUser;
            vm.resetData(redditUser);
            vm.getAccountInfo(redditUser);
            vm.getAllComments(redditUser);
            return {
                accountData: vm.accountData,
                bestComment: vm.bestComment,
                userName: vm.userName,
                subreddit: vm.subreddit,
                myChart: vm.myChart
            };
        }

        vm.resetData = function (user) {
            vm.accountData = {};
            vm.after = '';
            vm.bestComment = {};
            vm.bestComment.karma = -(Math.pow(2, 53) - 1);
            vm.userName = user;
            vm.date = '';
            vm.subreddit = [];
            vm.topThreeSub = [];
        }

        vm.getAccountInfo = function (user) {
            $http.get('https://www.reddit.com/user/' + user + '/about.json')
                .then(function (response) {
                    vm.accountData = response.data.data;
                    vm.accountData.total_karma = vm.accountData.comment_karma + vm.accountData.link_karma;
                    console.log("I got the account info!");
                });
        }
        vm.getAllComments = function (user) {
            $http.get('https://www.reddit.com/user/' + user + '/comments.json' + vm.after)
                .then(
                function (response) {
                    console.log("I got the comment info!");
                    tempResponse = response;
                    var data = response.data.data
                    vm.after = '?after=' + data.after;
                    for (i = 0; i < data.children.length; i++) {
                        if (vm.bestComment.karma < parseInt(data.children[i].data.score)) {
                            vm.bestComment.karma = parseInt(data.children[i].data.score);
                            vm.bestComment.comment = data.children[i].data.body;
                            vm.bestComment.date = (new Date(data.children[i].data.created * 1000)).toString();
                        }
                        var tempSub = data.children[i].data.subreddit;
                        if (vm.subreddit[tempSub] === undefined) {
                            vm.subreddit[tempSub] = 1;
                        }
                        else {
                            vm.subreddit[tempSub]++;
                        }
                    }
                    if (response.data.data.after != null) {
                        vm.getAllComments(user);
                    }
                }, function (error) {
                    console.log(error);
                    throw error;
                })
                .catch(function (error) { });
        }
        return {
            resolve: vm.resolve,
            hello: vm.hello,
            getAnalysisData: vm.getAnalysisData
        }
    }]);

I'm recursively calling the function vm.getAllComments because how it works is vm.getAllComments will get first 25 comments of the account, and then from part of the info from response, I can get the next 25 comments in the account.

and finally, in my redditanalyzer file, I have

angular.module('app')
    .component('redditAnalyzer', {
        templateUrl: 'Content/app/components/redditAnalyzer.html',
        bindings: {
            resolve: '<'
        },
        controller: ['$http', 'test',
            function ($http, test) {
                var vm = this;
                vm.accountData = {};
                vm.bestComment = {};
                vm.bestComment.karma = 0;
                vm.userName;
                vm.bestComment.date = '';
                vm.subreddit = {};
                vm.myChart;

                vm.$onInit = function () {
                    console.log("this is the resolve", vm.resolve);
                    //vm.accountData = resolve.accountData;
                    //vm.bestComment = resolve.bestComment;
                    //vm.myChart = resolve.myChart;
                    //vm.subreddit = resolve.subreddit;
                    //vm.userName = resolve.userName;
                }

            }]
    });

And you can see the problem in my console.

this is the resolve {accountData: {…}, bestComment: {…}, userName: "spez", subreddit: Array(0), myChart: undefined}accountData: {}bestComment: {karma: 22200, comment: "Reddit search might work by then.", date: "Thu Oct 27 2016 01:07:22 GMT-0400 (Eastern Daylight Time)"}myChart: undefinedsubreddit: [blog: 10, announcements: 475, modnews: 34, programming: 32, ModSupport: 20, …]userName: "spez"__proto__: Object
test.js:44 I got the account info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
test.js:51 I got the comment info!
7test.js:51 I got the comment info!

It changes the route even before doing the promises.
What should i do to wait for all of my promises?

Body:
I additional, what version of ui-router you are using? on the latest '$stateParams' is deprecated and relapsed with $transition$.

Also you don`t need to use this

url: '/analyze/:name',

In UI-Router legacy, a parameter found in the URL path was optional.
  If the parameter was not found in the URL, it would match the empty
  string.

You can replace with:

url: '/analyze/',

and

params: {
    name: ""
  }

You can read migration guid


问:
Merge maps and make values as array
```<code>public class MapCheck {
    public static void main(String[] args) {
        Map<String, String> data = new HashMap<String, String>();
        data.put("John", "Taxi Driver");
        data.put("Mark", "Professional Killer");
        Map<String, String> data1 = new HashMap<String, String>();
        data1.put("John", "Driver");
        data1.put("Mark", "Murderer");
        Map<String, String> data3 = new HashMap<String, String>();
        data3.putAll(data);
        data3.putAll(data1);
        System.out.println(data3);
    }
}
</code>```

I have few maps which contains same key, their values are different. I want to merge them. But when I merge them with the usual putAll() it gives me only the value of the key which was inserted latest.

Output from above code is  {John=Driver, Mark=Murderer}

Is there a method which will get me all the values associated with the key and give me as a array like

```<code>{John=[Taxi Driver, Driver], Mark=[Professional Killer, Murderer]}
</code>```

答:
Something like this?</p>

```<code>void add(String key, String value, Map<String,List<String>> map) {
    List<String> list = map.get(key);
    if (list == null) {
        list = new ArrayList<>();
        map.put(key, list);
    }
    list.add(value);
}
</code>```

Title: Merge maps and make values as array

Body:
public class MapCheck {
    public static void main(String[] args) {
        Map<String, String> data = new HashMap<String, String>();
        data.put("John", "Taxi Driver");
        data.put("Mark", "Professional Killer");
        Map<String, String> data1 = new HashMap<String, String>();
        data1.put("John", "Driver");
        data1.put("Mark", "Murderer");
        Map<String, String> data3 = new HashMap<String, String>();
        data3.putAll(data);
        data3.putAll(data1);
        System.out.println(data3);
    }
}

I have few maps which contains same key, their values are different. I want to merge them. But when I merge them with the usual putAll() it gives me only the value of the key which was inserted latest.

Output from above code is  {John=Driver, Mark=Murderer}

Is there a method which will get me all the values associated with the key and give me as a array like

{John=[Taxi Driver, Driver], Mark=[Professional Killer, Murderer]}

Body:
Something like this?

void add(String key, String value, Map<String,List<String>> map) {
    List<String> list = map.get(key);
    if (list == null) {
        list = new ArrayList<>();
        map.put(key, list);
    }
    list.add(value);
}


问:
Swift: How to put often used code into a single place to reuse it?
I am still trying to grasp all these programming concepts and I have a simple UIView with a rgb color and I am using this on many different views.

Right now I am still hard coding the color in every view:

```<code>UIColor(red: 120/255, green: 51/255, blue: 2/255, alpha: 1.0
</code>```

But I'd love to create a single swift file (called Colors.swift for instance) and there I'd like to put all colors.

Now in every single view I'd like to just get the color from this file, so that I have only one place to change the colors if necessary.

I know how to create a function in a swift file and call it from another place. For example all animations I reuse I place into one file, but with those colors I'm having a blackout. I have no idea how to place them into another file and get them out of there. Perfect would be some kind of switch case with different named colors (blue, green,...) and their corresponding rgb values so that I can just call the name of the color to get it. This would be a swift file I create:

```<code>import UIKit

let myColors = UIColor()

switch myColors {
case .red:
    UIColor(red: 120/255, green: 51/255, blue: 2/255, alpha: 1.0)
case .gray:
    UIColor(red: 120/255, green: 120/255, blue: 120/255, alpha: 1.0)
default:
    UIColor(red: 0/255, green: 0/255, blue: 0/255, alpha: 1.0)
}
</code>```

But when I write a switch statement in a swift file I cannot get this to work. The error I get is "statements are not allowed on top level" and each case gets the error "Results of UIColor initializer is unused", but I do not see a way to place it inside something?

Maybe the whole approach is wrong?

答:
You need to put it into a class. You can simply make the color variable static, so you don't need to instantiate the class:

```<code>class Colors: NSObject {
    static let color: = UIColor(red: 120/255, green: 51/255, blue: 2/255, alpha: 1.0)
}
</code>```

Then use it like this:

```<code>import Colors

Colors.color
</code>```

You can also define your enums there.

Body:
I am still trying to grasp all these programming concepts and I have a simple UIView with a rgb color and I am using this on many different views.

Right now I am still hard coding the color in every view:

UIColor(red: 120/255, green: 51/255, blue: 2/255, alpha: 1.0

But I'd love to create a single swift file (called Colors.swift for instance) and there I'd like to put all colors.

Now in every single view I'd like to just get the color from this file, so that I have only one place to change the colors if necessary.

I know how to create a function in a swift file and call it from another place. For example all animations I reuse I place into one file, but with those colors I'm having a blackout. I have no idea how to place them into another file and get them out of there. Perfect would be some kind of switch case with different named colors (blue, green,...) and their corresponding rgb values so that I can just call the name of the color to get it. This would be a swift file I create:

import UIKit

let myColors = UIColor()

switch myColors {
case .red:
    UIColor(red: 120/255, green: 51/255, blue: 2/255, alpha: 1.0)
case .gray:
    UIColor(red: 120/255, green: 120/255, blue: 120/255, alpha: 1.0)
default:
    UIColor(red: 0/255, green: 0/255, blue: 0/255, alpha: 1.0)
}

But when I write a switch statement in a swift file I cannot get this to work. The error I get is "statements are not allowed on top level" and each case gets the error "Results of UIColor initializer is unused", but I do not see a way to place it inside something?

Maybe the whole approach is wrong?

Body:
You need to put it into a class. You can simply make the color variable static, so you don't need to instantiate the class:

class Colors: NSObject {
    static let color: = UIColor(red: 120/255, green: 51/255, blue: 2/255, alpha: 1.0)
}

Then use it like this:

import Colors

Colors.color

You can also define your enums there.


问:
Replace class in order to replace image on click with jquery
I read a number of articles and answers here on Stack Overflow but none of them answered my question as I'm really a noob when it comes to jQuery and I'm not sure how to do this.

I have a HTML landing page on which I'm trying to show several images on which you click and they get replaced with another image and when clicked again or at another image the original one is shown.

I have this so far:

```<code><div class="santa">
  <img class="show" src="images/santa.png" alt="">
  <img class="hide" src="images/bubble.png" alt="">
</div>
</code>```

.hide { display: none; }
.show { display: block; }
```

I want to show santa.png by default and when clicked on to change it to bubble.png, meaning default class is show and when clicked on it's hide for santa and vice versa.

Thanks in advance!

答:
Since u are a beginner, my humble request is to learn vanillajs thoroughly before using libraries like jquery.

here is a pure js approach.. Cheers

let santaimg = document.getElementById('santa');
let bubbleimg = document.getElementById('bubble');

santaimg.onclick = showBubbleHideSanta;

function showBubbleHideSanta() {
 santaimg.classList += " hide";
 //santaimg.classList -= "show";
 bubbleimg.classList -= " hide";
 //bubbleimg.classList += "show";
}```
<pre class="snippet-code-css lang-css prettyprint-override"><code>.show {
  display:block;
}
.hide {
  display:none;
}</code>```

```

Body:
I read a number of articles and answers here on Stack Overflow but none of them answered my question as I'm really a noob when it comes to jQuery and I'm not sure how to do this.

I have a HTML landing page on which I'm trying to show several images on which you click and they get replaced with another image and when clicked again or at another image the original one is shown.

I have this so far:

.hide { display: none; }
.show { display: block; }

I want to show santa.png by default and when clicked on to change it to bubble.png, meaning default class is show and when clicked on it's hide for santa and vice versa.

Thanks in advance!

Body:
Since u are a beginner, my humble request is to learn vanillajs thoroughly before using libraries like jquery.

here is a pure js approach.. Cheers

let santaimg = document.getElementById('santa');
let bubbleimg = document.getElementById('bubble');

santaimg.onclick = showBubbleHideSanta;

function showBubbleHideSanta() {
 santaimg.classList += " hide";
 //santaimg.classList -= "show";
 bubbleimg.classList -= " hide";
 //bubbleimg.classList += "show";
}

.show {
  display:block;
}
.hide {
  display:none;
}

<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/49/Jonathan_G_Meath_portrays_Santa_Claus.jpg/220px-Jonathan_G_Meath_portrays_Santa_Claus.jpg" id="santa" class="show"/>
<img src = "https://sophosnews.files.wordpress.com/2017/05/shutterstock_296886146.jpg?w=780&h=408&crop=1" id="bubble" class="hide"/>


答:
You can use Swift Extensions for this functionality.

```<code>// Colors.swift
extension UIColor {

   var myCustomRed: UIColor {
      return UIColor(red: 120/255, green: 51/255, blue: 2/255, alpha: 1.0)
   }
}

// elsewhere in the app
view.backgroundColor = UIColor.myCustomRed
</code>```

You can place as many custom implementations in there as you like, just be careful not to use conflicting names with existing colours.

For more information refer to the docs Swift Extensions Documentation

UPDATE:

```<code>enum ThemeColors: UIColor {
    case red = UIColor(red: 120/255, green: 51/255, blue: 2/255, alpha: 1.0)
    case blue = UIColor(red: 2/255, green: 51/255, blue: 120/255, alpha: 1.0)
}

view.backgroundColor = ThemeColors.red
</code>```

Title: Swift: How to put often used code into a single place to reuse it?

Body:
You can use Swift Extensions for this functionality.

// Colors.swift
extension UIColor {

   var myCustomRed: UIColor {
      return UIColor(red: 120/255, green: 51/255, blue: 2/255, alpha: 1.0)
   }
}

// elsewhere in the app
view.backgroundColor = UIColor.myCustomRed

You can place as many custom implementations in there as you like, just be careful not to use conflicting names with existing colours.

For more information refer to the docs Swift Extensions Documentation

UPDATE:

enum ThemeColors: UIColor {
    case red = UIColor(red: 120/255, green: 51/255, blue: 2/255, alpha: 1.0)
    case blue = UIColor(red: 2/255, green: 51/255, blue: 120/255, alpha: 1.0)
}

view.backgroundColor = ThemeColors.red


答:
You may want to create Map<String, <ArrayList<String>>. That way you can store multiple values that are associated with one key.

You may consider creating method that provides storing multiple values associated to unique key in specified map:

```<code>public static void add(String key, String value, Map<String, List<String>> map) {
        // Here you create a refeREnce to instance of the list storing values associated with given key:
        List<String> listOfValues = map.get(key);
        // If given key was already present in the map...
        if(listOfValues != null) {
            // Add given value to list of values associated with given key:
            listOfValues.add(value);
        // If given key wasn't present in the map...
        } else {
            // Initialize an ArrayList that will store given value in the map:
            listOfValues = new ArrayList<>();
            // Put new entry into the given map (given key and to-be-filled list of values:
            map.put(key, listOfValues);
            // Put given value to the list of values associated with given key
            listOfValues.add(value);
        }
}
</code>```

Title: Merge maps and make values as array

Body:
You may want to create Map<String, <ArrayList<String>>. That way you can store multiple values that are associated with one key.

You may consider creating method that provides storing multiple values associated to unique key in specified map:

public static void add(String key, String value, Map<String, List<String>> map) {
        // Here you create a refeREnce to instance of the list storing values associated with given key:
        List<String> listOfValues = map.get(key);
        // If given key was already present in the map...
        if(listOfValues != null) {
            // Add given value to list of values associated with given key:
            listOfValues.add(value);
        // If given key wasn't present in the map...
        } else {
            // Initialize an ArrayList that will store given value in the map:
            listOfValues = new ArrayList<>();
            // Put new entry into the given map (given key and to-be-filled list of values:
            map.put(key, listOfValues);
            // Put given value to the list of values associated with given key
            listOfValues.add(value);
        }
}


问:
Excel freeze panes after scroll
I have an Excel spreadsheet with a pivot table containing many filters.
The headers I'd like to freeze are on line 25 of the sheet.
On any screen with a resolution smaller then 1920 x 1080 none of the row below will show while scrolling.

Is there a way to freeze the pane when a user scrolls down and line 25 if the top visible row, then unfreeze the panes again when the user scrolls up above line 25?

答:
To answer your question, yes, that should be possible:

Chip Pearson: Detecting Scrolling In A Worksheet Window

Stack Overflow: How to determine if a worksheet Cell is Visible/Displayed in VBA?

However, it would probably take you a lot less work to instead, reorganize your workbook so you're not using Row 25 as a header (ever).  It sounds like you might have "too much stuff" crammed onto one worksheet.  :-)

Title: Excel freeze panes after scroll


问:
File comparing APIs/Code
I have to program a file comparing - only (plain) text files and pdf files - algorithm. I allowed to use APIs or other codes.

What i have found:

Google match-diff libs

Windows file compare command

Linux diff command

Many libs that are based on google api or diff from linux

So they compare two files line by line but if i have for example this:

```<code>package pack1;

some imports

/**
 *
 * @author author1
 */
public class Class1 {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        System.out.print("ABaBAb " + count("ABaBAb") + "\n");
        System.out.print("ABCabC " + count("ABCabC") + "\n");
        System.out.print("ABaBAb " + count("ABaBAb") + "\n");
        System.out.print("ABCDabdf " + count("ABCDabdf") + "\n");
        System.out.print("ABCab " + count("ABCab") + "\n");
    }
    static HashMap<String, Integer> cache = new HashMap<>();

    public static int count(String s) {
        does something
    }
}
</code>```

and this:

```<code>package pack2;

some imports

/**
 *
 * @author changed
 */
public class Class2 {
static HashMap<String, Integer> cache = new HashMap<>();

    public static int count(String s) {
        does something
    }

    public static void main(String[] args) {

        System.out.print("asdff " + countDifferentChars("asdff") + "\n");
        System.out.print("Afda " + countDifferentChars("Afda") + "\n");
        System.out.print("ABab " + countDifferentChars("ABab") + "\n");
        System.out.print("sadr " + countDifferentChars("sadr") + "\n");
        System.out.print("Afasd " + countDifferentChars("Afasd") + "\n");
    }

}
</code>```

they do not really know the differences because they, as I said, compare line by line. I am looking for something that should know that package, the System.out.print and other things are nearly the same. It also should be able to tell that the count methods are the same (they only were moved).

Are there any APIs that are able to do this? Please do let me know if you have more questions.

Thank you in advance for helping

答: That looks like an AI task (understanding types of statements etc.). I am making something like this, but it isn't ready yet.</p>

Title: File comparing APIs/Code

Body:
I have to program a file comparing - only (plain) text files and pdf files - algorithm. I allowed to use APIs or other codes.

What i have found:

Google match-diff libs

Windows file compare command

Linux diff command

Many libs that are based on google api or diff from linux

So they compare two files line by line but if i have for example this:

package pack1;

some imports

/**
 *
 * @author author1
 */
public class Class1 {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        System.out.print("ABaBAb " + count("ABaBAb") + "\n");
        System.out.print("ABCabC " + count("ABCabC") + "\n");
        System.out.print("ABaBAb " + count("ABaBAb") + "\n");
        System.out.print("ABCDabdf " + count("ABCDabdf") + "\n");
        System.out.print("ABCab " + count("ABCab") + "\n");
    }
    static HashMap<String, Integer> cache = new HashMap<>();

    public static int count(String s) {
        does something
    }
}

and this:

package pack2;

some imports

/**
 *
 * @author changed
 */
public class Class2 {
static HashMap<String, Integer> cache = new HashMap<>();

    public static int count(String s) {
        does something
    }

    public static void main(String[] args) {

        System.out.print("asdff " + countDifferentChars("asdff") + "\n");
        System.out.print("Afda " + countDifferentChars("Afda") + "\n");
        System.out.print("ABab " + countDifferentChars("ABab") + "\n");
        System.out.print("sadr " + countDifferentChars("sadr") + "\n");
        System.out.print("Afasd " + countDifferentChars("Afasd") + "\n");
    }

}

they do not really know the differences because they, as I said, compare line by line. I am looking for something that should know that package, the System.out.print and other things are nearly the same. It also should be able to tell that the count methods are the same (they only were moved).

Are there any APIs that are able to do this? Please do let me know if you have more questions.

Thank you in advance for helping


问:
check duplicate numbers with bool function in matrix c++
I created a matrix[10][10] with random numbers

```<code>for (int i = 0; i < 10; i++)
{
    for (int j = 0; j < 10; j++)
    {
        matrix[i][j] = rand() % 100 ;

    }
}
</code>```

But I need to use bool function for check duplicate numbers and if its same use random again.How can i do it?

答:
There are multiple ways to achieve this.

Write a function which returns bool and takes 10*10 matrix size. Compute sum of all numbers. Compare this result with the sum of numbers from 1...99. If both matches then no duplicate return true, otherwise duplicate return false. Sum of 1..99 can be calculated using n(n+1)/2, where n = 99.

In function create array of size 100. Initialize all array elements with 0. Iterate over matrix, use matrix element as index of array. If array contains 1 at that position you got duplicate element otherwise make array element at that index 0.

Implementation of first approach

```<code>#include <iostream>
#include <cstdlib>
#include <iomanip>

#define ROW 10
#define COL 10
#define MOD 100

int main()
{
 int mat[ROW][COL];
 int sum = 0;
 int range_sum = ((MOD-1)*(MOD))/2; // n = MOD-1, sum = n(n+1)/2
 while(true){
    sum = 0;
    for(int i = 0; i < ROW; i++){
        for(int j = 0; j < COL; j++){
            mat[i][j] = rand()%MOD;
            sum += mat[i][j];
        }
    }
    if(sum==range_sum){
        break;
    }

 }

 for(int i = 0; i < ROW; i++){
    for(int j = 0; j < COL; j++){
        std::cout << std::setw(2) << mat[i][j] << "  ";
        }
        std::cout << std::endl;
    }

 return 0;
}
</code>```

Body:
I created a matrix[10][10] with random numbers

for (int i = 0; i < 10; i++)
{
    for (int j = 0; j < 10; j++)
    {
        matrix[i][j] = rand() % 100 ;

    }
}

But I need to use bool function for check duplicate numbers and if its same use random again.How can i do it?

Body:
There are multiple ways to achieve this.

Write a function which returns bool and takes 10*10 matrix size. Compute sum of all numbers. Compare this result with the sum of numbers from 1...99. If both matches then no duplicate return true, otherwise duplicate return false. Sum of 1..99 can be calculated using n(n+1)/2, where n = 99.

In function create array of size 100. Initialize all array elements with 0. Iterate over matrix, use matrix element as index of array. If array contains 1 at that position you got duplicate element otherwise make array element at that index 0.

Implementation of first approach

#include <iostream>
#include <cstdlib>
#include <iomanip>

#define ROW 10
#define COL 10
#define MOD 100

int main()
{
 int mat[ROW][COL];
 int sum = 0;
 int range_sum = ((MOD-1)*(MOD))/2; // n = MOD-1, sum = n(n+1)/2
 while(true){
    sum = 0;
    for(int i = 0; i < ROW; i++){
        for(int j = 0; j < COL; j++){
            mat[i][j] = rand()%MOD;
            sum += mat[i][j];
        }
    }
    if(sum==range_sum){
        break;
    }

 }

 for(int i = 0; i < ROW; i++){
    for(int j = 0; j < COL; j++){
        std::cout << std::setw(2) << mat[i][j] << "  ";
        }
        std::cout << std::endl;
    }

 return 0;
}