问:
Service timed out: Spreadsheets
I always get the exception: "Exception: Service timed out: Spreadsheets" Why does this happen and would it help to try the method updateSpec(spec)? It always happens when I got to this specific line:

```<code>let turnamentGames = response("https://europe.api.riotgames.com/lol/match/v5/matches/by-puuid/" + puuid + "/ids?type=tourney&start=0&count=100&startTime=" + (parseInt((currentTime / 1000) - 15552000)) + "&" + apikey.substring(1));
</code>```

It also takes a long time (30s) to run the first output of the initial methods first line:

```<code>function main() {
  console.info("MAIN: STARTED");
  currentTime = new Date();
  if (currentTime.getHours() > 11) analyse();
  else console.warn("MAIN: Next search at 12:00");
}
</code>```

This should not be that complicated. Is it then just a issue of bad Google servers or what is the problem?

I appreciate any help.

Full code:

```<code>function analyse() {
  let firstTeamName = spreadsheet.getSheetByName("Übersicht").getRange("AZ1:AZ1").getValue();
  console.info("MAIN: (1/9) Teams loaded");
  analyseTeam(spreadsheet.getSheetByName(firstTeamName));
  analyseTeam(spreadsheet.getSheetByName("TRUEs"));
  for (let id = 1; id < 8; ++id) if (id !== Number(firstTeamName.startsWith("Tag ") ? firstTeamName.substring(4) : 0)) analyseTeam(spreadsheet.getSheetByName("Tag " + id));
}

function response(url) {
  response(url, 1);
}

function response(url, id) {
  makeABreak.push(new Date().getTime());
  if (makeABreak.length === 100) {
    if ((new Date().getTime() - makeABreak.shift()) < 120000) {
      console.warn("I make a break!");
      Utilities.sleep(120000);
      makeABreak = [];
    }
  }
  try {
    return JSON.parse(UrlFetchApp.fetch(url).getContentText());
  } catch(exception) {
    console.error("Exception for (" + url + "):" + exception);
    return id === 2 ? null : response(url, 2);
  }
</code>```
```let sheet;
let puuids;
let newPlayers;
let section;
let sectionRow;
let sectionLine;
let lineRecentGames;
let normsInSection;

function analyseTeam(sheetToAnalyse) {
  // Initializing
  currentTime = new Date();
  sheet = sheetToAnalyse;
  puuids = [];
  newPlayers = [];
  normsInSection = [];
  section = -1;
  sectionRow = -1;
  sectionLine = -1;
  lineRecentGames = (sheet.getName() === "TRUEs" ? 22 : 17);

  // Load player Data & Custom Games
  let games = loadPlayers();
  console.info(sheet.getName() + ": Spieler geladen, Elos aktualisiert");
  games.sort();
  findPrimeLeague(games);
  console.info(sheet.getName() + ": PrimeLeague Spiele geladen.");

  // Load Normal Games
  findNorms();
  console.info("MAIN: " + sheet.getName() + " loaded");
}

function loadPlayers() {
  let recentCustomGames = [];
  let recentCustomGamesData = sheet.getRange(lineRecentGames + 2, 1, 250, 1).getValues();
  for (let customGameId in recentCustomGamesData) {
    if (recentCustomGamesData.hasOwnProperty(customGameId)) {
      recentCustomGames.push(recentCustomGamesData[customGameId][0]);
      if (recentCustomGamesData[customGameId][1] == "" || new Date().getTime() - new Date(recentCustomGamesData[customGameId][1]).getTime() > 15552000000)
        sheet.getRange(lineRecentGames + 2 + customGameId, 1, 1, 73).setValues([["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
          "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""]]);
    }
  }
  let games = [];
  let column = 22;
  let names = [];

  let playerData = sheet.getRange(2, 1, sheet.getName() === "TRUEs" ? 20 : 15, 3).getValues();
  let puuid;
  let summonerData;
  let elo = "U";
  for (let playerId in playerData) {
    if (playerData.hasOwnProperty(playerId)) {
      puuid = playerData[playerId][1];
      // Insert new Players
      if (puuid.length < 10) {
        if (playerData[playerId][0] !== "") {
          let profileContent = response('https://euw1.api.riotgames.com/lol/summoner/v4/summoners/by-name/' + playerData[playerId][0] + apikey);
          puuid = profileContent.puuid;
          playerData[playerId][1] = profileContent.puuid;
          newPlayers.push(puuid);
        }
      } else {
        if (currentTime.getHours() === 23) {
          summonerData = response('https://euw1.api.riotgames.com/lol/summoner/v4/summoners/by-puuid/' + puuid + apikey);
          playerData[playerId][0] = summonerData.name;

          if (sheet.getName().startsWith("Tag")) column = Number(sheet.getName().substring(4));
          else if (sheet.getName() === "Scrim") column = 8;
          else {
            let scrimTeams = inputSheet.getRange(2, 12, 1, Number(inputSheet.getRange("C2:C2").getValue())).getValues()[0];
            for (let scrimTeam in scrimTeams) if (scrimTeams.hasOwnProperty(scrimTeam) && String(scrimTeams[scrimTeam]) === sheet.getName()) column = scrimTeam + 9;
          }
          //RANKED
          let rankedData = response('https://euw1.api.riotgames.com/lol/league/v4/entries/by-summoner/' + summonerData.id + apikey);
          for (let entry in rankedData) {
            if (rankedData.hasOwnProperty(entry) && rankedData[entry].queueType === "RANKED_SOLO_5x5")
              elo = String(rankedData[entry].tier).substring(0, 1) + (rankedData[entry].rank === "I" ? "1" : rankedData[entry].rank === "II" ? "2" : rankedData[entry].rank === "III"?"3":"4");
          }
          playerData[playerId][2] = elo;
        }
      }
      puuids.push(puuid);

      if (puuid !== "" && playerId < 10) {
        let turnamentGames = response("https://europe.api.riotgames.com/lol/match/v5/matches/by-puuid/" + puuid + "/ids?type=tourney&start=0&count=100&startTime=" + (parseInt((currentTime / 1000) - 15552000)) + "&" + apikey.substring(1));
        for (let turnamentGame in turnamentGames) if (turnamentGames.hasOwnProperty(turnamentGame) && !games.includes(turnamentGames[turnamentGame]) && !recentCustomGames.includes(turnamentGames[turnamentGame])) games.push(turnamentGames[turnamentGame]);

        let clashGames = response("https://europe.api.riotgames.com/lol/match/v5/matches/by-puuid/" + puuid + "/ids?startTime=" + (parseInt((currentTime / 1000) - 15552000)) +
            "&queue=700&start=0&count=100&" + apikey.substring(1));
        for (let clashGame in clashGames) if (clashGames.hasOwnProperty(clashGame) && !games.includes(clashGames[clashGame]) && !recentCustomGames.includes(clashGames[clashGame]))
          games.push(clashGames[clashGame]);
      }
      names.push(new Array(playerData[playerId][0]));
      playerData[playerId].splice(0, 1);
    }
  }
  //determineAmountofTourneyGames(playerData);
  inputSheet.getRange(4, column + 3, playerData.length, 1).setValues(names);
  sheet.getRange(2, 2, playerData.length, 2).setValues(playerData);
  return games;
}

function findPrimeLeague(games) {
  const championData = response("http://ddragon.leagueoflegends.com/cdn/" + response("http://ddragon.leagueoflegends.com/api/versions.json")[0] + "/data/en_US/champion.json");
  let startAmount = Number(sheet.getRange("B" + lineRecentGames + ":B" + lineRecentGames).getValue());
  let amount = Number(startAmount);
  let gamesArrays = [];
  let ganks = sheet.getRange("P1:R1").getValues()[0]

  for (let game in games) {
    if (games.hasOwnProperty(game)) {
      let gameId = games[game];
      let gameData = response("https://europe.api.riotgames.com/lol/match/v5/matches/" + gameId + apikey);
      let durationSeconds = Number(gameData.info.gameDuration);
      if (durationSeconds > 36000) durationSeconds = Math.round(durationSeconds / 1000);

      //determineTeam
      let team;
      let win;
      let players = gameData.info.participants;
      for (let playerId in players) {
        if (players.hasOwnProperty(playerId)) {
          let participant = players[playerId];
          if (puuids.includes(participant.puuid)) {
            team = participant.teamId;
            win = participant.win;
            break;
          }
        }
      }

      let teams = gameData.info.teams;
      let banns = [];
      let banIds = team === 200 ? (teams[1].bans).concat(teams[0].bans) : (teams[0].bans).concat(teams[1].bans);
      if (championData !== undefined) {
        let champions = championData.data;
        for (let champion in champions) if (champions.hasOwnProperty(champion))
          for (let ban in banIds) if (banIds.hasOwnProperty(ban) && banIds[ban].championId === Number(champions[champion].key)) banns.push(champions[champion].id);
      }

      let top = ["", "", "", "", "", "", "", "", "", ""];
      let jgl = ["", "", "", "", "", "", "", "", "", ""];
      let mid = ["", "", "", "", "", "", "", "", "", ""];
      let bot = ["", "", "", "", "", "", "", "", "", ""];
      let sup = ["", "", "", "", "", "", "", "", "", ""];
      let totalCS = 0;
      let supGold;
      for (let playerId in players) {
        if (players.hasOwnProperty(playerId)) {
          let participant = players[playerId];
          if (puuids.includes(participant.puuid)) totalCS += (parseInt(participant.neutralMinionsKilled) + parseInt(participant.totalMinionsKilled));
          if (participant.teamPosition === "TOP") top = determinePlayer(participant, top);
          if (participant.teamPosition === "JUNGLE") jgl = determinePlayer(participant, jgl);
          if (participant.teamPosition === "MIDDLE") mid = determinePlayer(participant, mid);
          if (participant.teamPosition === "BOTTOM") bot = determinePlayer(participant, bot);
          if (participant.teamPosition === "UTILITY") sup = determinePlayer(participant, sup);
          if (puuids.includes(participant.puuid) && participant.teamPosition === "UTILITY") supGold = participant.goldEarned;
        }
      }

      let gameDetails = response("https://europe.api.riotgames.com/lol/match/v5/matches/" + gameId + "/timeline" + apikey);
      let detailedParticipants = gameDetails.metadata.participants;
      let topId = -1;
      let jglId = -1;
      let midId = -1;
      let botId = -1;
      let supId = -1;
      for (let participant in detailedParticipants) {
        if (detailedParticipants.hasOwnProperty(participant)) {
          if (detailedParticipants[participant] === top[0]) topId = Number(participant) + 1;
          else if (detailedParticipants[participant] === jgl[0]) jglId = Number(participant) + 1;
          else if (detailedParticipants[participant] === mid[0]) midId = Number(participant) + 1;
          else if (detailedParticipants[participant] === bot[0]) botId = Number(participant) + 1;
          else if (detailedParticipants[participant] === sup[0]) supId = Number(participant) + 1;
        }
      }

      let topSoloKills = 0;
      let jglSuccessGanks = 0;
      let jglTriedGanks = 0;
      let midSoloKills = 0;
      let botMinions = 0;
      let supSuccessGanks = 0;
      let recentDamageStats = 0;
      let totalDamage = 0;
      for (let frameId in gameDetails.info.frames) {
        let events = gameDetails.info.frames[frameId].events;
        for (let eventObj in events) {
          if (events.hasOwnProperty(eventObj)) {
            let event = events[eventObj];
            let assistingIds = event.assistingParticipantIds;
            if (event.type === "CHAMPION_KILL" && assistingIds === undefined && topId > 0 && event.killerId === topId) topSoloKills++;
            if (event.type === "CHAMPION_KILL" && assistingIds === undefined && midId > 0 && event.killerId === midId) midSoloKills++;
            if (event.type === "CHAMPION_KILL" && event.timestamp < 1000000) {
              if (jglId > 0 && event.killerId === jglId) {
                if ((event.position.x - event.position.y) < -3000) {
                  ++ganks[0];
                } else if ((event.position.x - event.position.y) > 3000) {
                  ++ganks[2];
                } else {
                  ++ganks[1];
                }
                jglSuccessGanks++;
              }
              for (let ids in assistingIds)
                if (assistingIds.hasOwnProperty(ids) && jglId > 0 && assistingIds !== undefined && assistingIds[ids] === jglId) {
                  if ((event.position.x - event.position.y) < -3000) {
                    ++ganks[0];
                  } else if ((event.position.x - event.position.y) > 3000) {
                    ++ganks[2];
                  } else {
                    ++ganks[1];
                  }
                  jglSuccessGanks++;
                }
              for (let ids in assistingIds) if (assistingIds.hasOwnProperty(ids) && supId > 0 && assistingIds !== undefined && assistingIds[ids] === supId &&
                  (event.killerId === midId || event.killerId === topId)) supSuccessGanks++;
            }
            if (event.type === "CHAMPION_KILL" && event.victimId === jglId && event.timestamp < 1000000) {
              if ((event.position.x - event.position.y) < -3000) {
                ++ganks[0];
              } else if ((event.position.x - event.position.y) > 3000) {
                ++ganks[2];
              } else {
                ++ganks[1];
              }
            }
          }
        }
        let frame = gameDetails.info.frames[frameId];
        if (jglId > 0 && frameId < 16) {
          totalDamage = frame.participantFrames[jglId].damageStats.totalDamageDoneToChampions;
          if (recentDamageStats !== totalDamage) jglTriedGanks++;
        }
        if (frameId == 15 && botId > 0) botMinions = frame.participantFrames[botId].minionsKilled + frame.participantFrames[botId].jungleMinionsKilled;
        recentDamageStats = totalDamage;
      }

      top[9] = (topId === -1) ? "" : topSoloKills;
      jgl[9] = (jglId === -1) ? "" : jglSuccessGanks / jglTriedGanks;
      mid[9] = (midId === -1) ? "" : midSoloKills;
      bot[9] = (botId === -1) ? "" : botMinions;
      sup[9] = (supId === -1) ? "" : supSuccessGanks;

      let date = Utilities.formatDate(new Date(Number(gameData.info.gameCreation)), CalendarApp.getTimeZone(), 'dd.MM.YYYY HH:mm');
      let type = gameData.info.gameType === "MATCHED_GAME" ? "C" : "L";
      let totalGold = parseInt(top[6] === "" ? 0 : top[6]) + parseInt(jgl[6] === "" ? 0 : jgl[6]) + parseInt(mid[6] === "" ?
          0 : mid[6]) + parseInt(bot[6] === "" ? 0 : bot[6]) + parseInt(supGold === "" ? 0 : supGold);
      let objectives = (team === 100) ? gameData.info.teams[0].objectives : gameData.info.teams[1].objectives;
      let tower = (team === 100 ? objectives.tower.kills : objectives.tower.kills);
      let drakes = (team === 100 ? objectives.dragon.kills : objectives.dragon.kills);
      let inhibs = (team === 100 ? objectives.inhibitor.kills : objectives.inhibitor.kills);
      let heralds = (team === 100 ? objectives.riftHerald.kills : objectives.riftHerald.kills);
      let barons = (team === 100 ? objectives.baron.kills : objectives.baron.kills);
      let gameArray = [gameId, date, durationSeconds, type, win, banns[0], banns[1], banns[2], banns[3], banns[4], banns[5], banns[6], banns[7], banns[8], banns[9], top[0], top[1], top[2],
        top[3], top[4], top[5], top[6], top[7], top[8], jgl[0], jgl[1], jgl[2], jgl[3], jgl[4], jgl[5], jgl[6], jgl[7], jgl[8], mid[0], mid[1], mid[2], mid[3], mid[4], mid[5], mid[6], mid[7],
        mid[8], bot[0], bot[1], bot[2], bot[3], bot[4], bot[5], bot[6], bot[7], bot[8], sup[0], sup[1], sup[2], sup[3], sup[4], sup[5], sup[6], sup[7], sup[8], totalCS, totalGold,
        tower, drakes, inhibs, heralds, barons, top[9], jgl[9], mid[9], bot[9], sup[9]];
      if (sheet.getName() === "TRUEs") gameArray.splice(60, 0, supGold); else gameArray.push("");
      gamesArrays.push(gameArray);
      ++amount;
    }
  }

  if (gamesArrays.length > 0) {
    if (startAmount % 250 < amount % 250) sheet.getRange(lineRecentGames + 2 + (startAmount % 250), 1, gamesArrays.length, gamesArrays[0].length).setValues(gamesArrays);
    else {
      let remainingSpace = 250 - (startAmount % 250);
      let lastArray = gamesArrays.slice(remainingSpace);
      sheet.getRange(lineRecentGames + 2 + (startAmount % 250), 1, remainingSpace, gamesArrays[0].length).setValues(gamesArrays.slice(0, remainingSpace));
      sheet.getRange(lineRecentGames + 2, 1, lastArray.length, gamesArrays[0].length).setValues(lastArray);
    }
  }
  sheet.getRange("B" + lineRecentGames + ":B" + lineRecentGames).setValue(amount);
  sheet.getRange("P1:R1").setValues([ganks]);
}

// TODO CALC!A1
function findNorms() {
  let allgames = [];
  let time = Number(sheet.getRange("K1:K1").getValue());
  if (time === 0) sheet.getRange("L1:L1").setValue("init");
  let recentNumber = Number(sheet.getRange("B1:B1").getValue());
  let amount = Number(sheet.getRange("CM1:CM1").getValue());
  let init = String(sheet.getRange("L1:L1").getValue()) === "init";
  if (init) {
    if (amount > 0) {
      let initAddNorms = sheet.getRange(3, 91, amount, 1).getValues();
      for (let normId in initAddNorms) {
        let norm = initAddNorms[normId][0];
        if (initAddNorms.hasOwnProperty(normId) && !allgames.includes(norm)) {
          allgames.push(norm);
        }
      }
    } else allgames = addPlayersGames(puuids, allgames);

    console.log(allgames.length);
  } else {
    if (time < parseInt((currentTime / 1000) - 15552000)) time = parseInt((currentTime / 1000) - 15552000)
    for (let puuid in puuids) {
      if (puuids.hasOwnProperty(puuid) && puuids[puuid] !== "" && puuids[puuid] !== undefined) {
        let games40 = response("https://europe.api.riotgames.com/lol/match/v5/matches/by-puuid/" + puuids[puuid] + "/ids?startTime=" +time+"&queue=400&start=0&count=100&"+apikey.substring(1));
        for (let game in games40) if(games40.hasOwnProperty(game) && !allgames.includes(games40[game]) && Number(String(games40[game]).substring(5))>recentNumber) allgames.push(games40[game]);
        let games42 = response("https://europe.api.riotgames.com/lol/match/v5/matches/by-puuid/" + puuids[puuid] + "/ids?startTime=" +time+"&queue=420&start=0&count=100&"+apikey.substring(1));
        for (let game in games42) if(games42.hasOwnProperty(game) && !allgames.includes(games42[game]) && Number(String(games42[game]).substring(5))>recentNumber) allgames.push(games42[game]);
        let games44 = response("https://europe.api.riotgames.com/lol/match/v5/matches/by-puuid/" + puuids[puuid] + "/ids?startTime=" +time+"&queue=440&start=0&count=100&"+apikey.substring(1));
        for (let game in games44) if(games44.hasOwnProperty(game) && !allgames.includes(games44[game]) && Number(String(games44[game]).substring(5))>recentNumber) allgames.push(games44[game]);
      }
    }
  }

  for (let game in allgames) if (Number(allgames[game].substring(5)) < recentNumber) allgames.splice(game, 1);
  if (newPlayers.length > 0 && !init) allgames = addPlayersGames(newPlayers, allgames);
  allgames.sort();
  console.info(sheet.getName() + ": " + ((allgames.length === 0) ? "No more matches " : allgames.length + " new matches"));
  if (allgames.length > 0) {
    let initNormsArray = [];
    for (let i = 0; i < allgames.length; ++i) initNormsArray.push("");

    if (init && allgames.length > 0) {
      for (let normId in allgames) if (allgames.hasOwnProperty(normId)) initNormsArray[normId] = [allgames[normId]];
      sheet.getRange(3, 91, initNormsArray.length, 1).setValues(initNormsArray);
    }
    for (let game in allgames) {
      let gameContent = response("https://europe.api.riotgames.com/lol/match/v5/matches/" + allgames[game] + apikey);
      if (response !== undefined && gameContent !== undefined) performGame(gameContent, gameContent.info.participants);
      else console.error(allgames[game] + " skipped");
    }
    if (normsInSection.length > 0) sheet.getRange(sectionLine, sectionRow, normsInSection.length, 16).setValues(normsInSection);
    sheet.getRange("K1:K1").setValue(parseInt(Number(currentTime.getTime()) / 1000));
    if (init) {
      for (let normId in allgames) if (allgames.hasOwnProperty(normId)) initNormsArray[normId] = [allgames[normId]];
      sheet.getRange(3, 91, initNormsArray.length, 1).setValues(initNormsArray);
      console.log("OUT");
    }
  }

  if (init) sheet.getRange("L1:L1").setValue("");
}

function performGame(game, players) {
  let timestamp = Number(game.info.gameCreation);
  let sectionNew = (parseInt((new Date(timestamp).getTime() - new Date('June 16, 2021 00:00:00 +0000').getTime()) / 864000000)) % 20 + 1;
  if (sectionNew !== section) {
    if (normsInSection.length > 0) sheet.getRange(sectionLine, sectionRow, normsInSection.length, 16).setValues(normsInSection);
    normsInSection = [];
    section = sectionNew;
    let sectionRowBig = (section === 1) ? (section + 3) : (section + 4);
    sectionRow = (sectionRowBig % 5 === 4) ? 74 : (sectionRowBig % 5 * 17 + 1);
    sectionLine = sheet.getRange("BL" + (300 + section) + ":BL" + (300 + section)).getValue() + (parseInt(sectionRowBig / 5) * 500) + 1;
  }

  let duration = game.info.gameDuration;
  let matchId = game.metadata.matchId;
  let date = Utilities.formatDate(new Date(timestamp), CalendarApp.getTimeZone(), 'dd.MM.YYYY HH:mm');
  for (let playerId in players) {
    if (players.hasOwnProperty(playerId)) {
      let participant = players[playerId];
      if (puuids.includes(participant.puuid)) {
        let lane = participant.teamPosition;
        let puuid = participant.puuid;
        let champion = participant.championName;
        let enemy = "";
        let win = participant.win;
        let cs = (participant.neutralMinionsKilled + participant.totalMinionsKilled) * 60 / ((duration > 10000) ? (duration / 1000) : duration);
        cs = Math.round(cs * 10) / 10;
        let gold = participant.goldEarned;
        let egold = 0;
        for (let enemyPlayer in players) {
          if (players.hasOwnProperty(enemyPlayer)) {
            let counterpart = players[enemyPlayer];
            if (counterpart.teamPosition === lane && counterpart.puuid !== puuid) {
              enemy = counterpart.championName;
              egold = counterpart.goldEarned;
              break;
            }
          }
        }
        let gdiff = (egold > 0) ? gold - egold : 0;
        let gpm = parseInt(gold * 60 / ((duration > 10000) ? (duration / 1000) : duration));
        let ad = participant.physicalDamageDealtToChampions;
        let ap = participant.magicDamageDealtToChampions;
        let td = participant.trueDamageDealtToChampions;
        let taken = participant.totalDamageTaken;
        let healed = participant.totalHeal;
        let cc = participant.timeCCingOthers;
        normsInSection.push([matchId, date, lane, puuid, champion, enemy, win, cs, gdiff, gpm, ad, ap, td, taken, healed, cc]);
      }
    }
  }
  sheet.getRange("B1:B1").setValue(matchId.substring(5));
}

function fetchResponses(puuid, epoch) {
  let matchIds = [];
  let contentEpoch = fetchresponse(puuid, epoch, "400");
  for (let matchId in contentEpoch) if (contentEpoch.hasOwnProperty(matchId) && !matchIds.includes(contentEpoch[matchId])) matchIds.push(contentEpoch[matchId]);
  contentEpoch = fetchresponse(puuid, epoch, "420");
  for (let matchId in contentEpoch) if (contentEpoch.hasOwnProperty(matchId) && !matchIds.includes(contentEpoch[matchId])) matchIds.push(contentEpoch[matchId]);
  contentEpoch = fetchresponse(puuid, epoch, "440");
  for (let matchId in contentEpoch) if (contentEpoch.hasOwnProperty(matchId) && !matchIds.includes(contentEpoch[matchId])) matchIds.push(contentEpoch[matchId]);
  return matchIds;
}

function fetchresponse(puuid, epoch, queueId) {
  return response("https://europe.api.riotgames.com/lol/match/v5/matches/by-puuid/" + puuid + "/ids?startTime=" + (parseInt(currentTime / 1000) - (3000000 * epoch)) + "&endTime=" +
      (parseInt(currentTime / 1000) - (3000000 * (epoch - 1))) + "&queue=" + queueId + "&start=0&count=100&" + apikey.substring(1));
}

function determinePlayer(participant, array) {
  return puuids.includes(participant.puuid) ? [participant.puuid, participant.championName, array[2], participant.kills, participant.deaths, participant.assists, (participant.teamPosition ===
      "UTILITY") ? participant.visionScore : participant.goldEarned, (participant.teamPosition === "UTILITY") ? participant.visionWardsBoughtInGame : participant.totalDamageDealtToChampions,
    array[8], array[9]] : [array[0], array[1], participant.championName, array[3], array[4], array[5], array[6], array[7], participant.goldEarned, array[9]];
}

function addPlayersGames(puuids, allgames) {
  console.log("Load " + puuids);
  for (let puuid in puuids) {
    if (puuids.hasOwnProperty(puuid)) {
      for (let epochId = 1; epochId < 11; ++epochId) {
        let contentEpoch = fetchResponses(puuids[puuid], epochId);
        for (let matchId in contentEpoch) if (!allgames.includes(contentEpoch[matchId])) allgames.push(contentEpoch[matchId]);
      }
    }
  }
  return allgames;
}

function determineAmountofTourneyGames(playerData) {
  let alltourneygamesAmountArray = [];
  for (let playerId in playerData) {
    if (playerData.hasOwnProperty(playerId)) {
      let puuid = playerData[playerId][1];
      alltourneygamesAmountArray.push((puuid.length > 10) ? ([response("https://europe.api.riotgames.com/lol/match/v5/matches/by-puuid/" + puuid + "/ids?type=tourney&start=0&count=100&" + apikey.substring(1)).length]) : ([0]));
    }
  }
  sheet.getRange(2, 21, playerData.length, 1).setValues(alltourneygamesAmountArray);
}
```

答:
The cause of the error is that you are calling sheet too many times, and each call is a request which takes time to process and ultimately leads to the timeout. The easy sounding solution is reduce the calls of sheet.getRange() and sheet.setValue() and sheet.getName() etc… so that you ideally do them once per each sheet you are working on. A simple example would be as follows, where everything is done once (except the api call, which ideally should also be done using a bulk api).

```<code>function writePlayersApiResToSheet( sheet ){
  // get all players data from the sheet in only 1 call
  const allPlayers = sheet.getDataRange().getValues()

  // remove the header in row 1
  allPlayers.shift()

  // api responses will be pushed here
  const output = []

  // do something, like call the api for each user
  allPlayers.forEach( player=> output.push([getPlayerInfoFromApi(player)]) )

  // write to the sheet once
  const startRow = 2
  const startCol = 10 // or wherever the api res should go
  sheet.getRange( startRow, startCol, allPlayers.length, 1).setValues( output )
}
</code>```

Google provides this Documentation on this topics.

Title: Service timed out: Spreadsheets

Body:
I always get the exception: "Exception: Service timed out: Spreadsheets" Why does this happen and would it help to try the method updateSpec(spec)? It always happens when I got to this specific line:

let turnamentGames = response("https://europe.api.riotgames.com/lol/match/v5/matches/by-puuid/" + puuid + "/ids?type=tourney&start=0&count=100&startTime=" + (parseInt((currentTime / 1000) - 15552000)) + "&" + apikey.substring(1));

It also takes a long time (30s) to run the first output of the initial methods first line:

function main() {
  console.info("MAIN: STARTED");
  currentTime = new Date();
  if (currentTime.getHours() > 11) analyse();
  else console.warn("MAIN: Next search at 12:00");
}

This should not be that complicated. Is it then just a issue of bad Google servers or what is the problem?

I appreciate any help.

Full code:

function analyse() {
  let firstTeamName = spreadsheet.getSheetByName("Übersicht").getRange("AZ1:AZ1").getValue();
  console.info("MAIN: (1/9) Teams loaded");
  analyseTeam(spreadsheet.getSheetByName(firstTeamName));
  analyseTeam(spreadsheet.getSheetByName("TRUEs"));
  for (let id = 1; id < 8; ++id) if (id !== Number(firstTeamName.startsWith("Tag ") ? firstTeamName.substring(4) : 0)) analyseTeam(spreadsheet.getSheetByName("Tag " + id));
}

function response(url) {
  response(url, 1);
}

function response(url, id) {
  makeABreak.push(new Date().getTime());
  if (makeABreak.length === 100) {
    if ((new Date().getTime() - makeABreak.shift()) < 120000) {
      console.warn("I make a break!");
      Utilities.sleep(120000);
      makeABreak = [];
    }
  }
  try {
    return JSON.parse(UrlFetchApp.fetch(url).getContentText());
  } catch(exception) {
    console.error("Exception for (" + url + "):" + exception);
    return id === 2 ? null : response(url, 2);
  }

let sheet;
let puuids;
let newPlayers;
let section;
let sectionRow;
let sectionLine;
let lineRecentGames;
let normsInSection;

function analyseTeam(sheetToAnalyse) {
  // Initializing
  currentTime = new Date();
  sheet = sheetToAnalyse;
  puuids = [];
  newPlayers = [];
  normsInSection = [];
  section = -1;
  sectionRow = -1;
  sectionLine = -1;
  lineRecentGames = (sheet.getName() === "TRUEs" ? 22 : 17);

  // Load player Data & Custom Games
  let games = loadPlayers();
  console.info(sheet.getName() + ": Spieler geladen, Elos aktualisiert");
  games.sort();
  findPrimeLeague(games);
  console.info(sheet.getName() + ": PrimeLeague Spiele geladen.");

  // Load Normal Games
  findNorms();
  console.info("MAIN: " + sheet.getName() + " loaded");
}

function loadPlayers() {
  let recentCustomGames = [];
  let recentCustomGamesData = sheet.getRange(lineRecentGames + 2, 1, 250, 1).getValues();
  for (let customGameId in recentCustomGamesData) {
    if (recentCustomGamesData.hasOwnProperty(customGameId)) {
      recentCustomGames.push(recentCustomGamesData[customGameId][0]);
      if (recentCustomGamesData[customGameId][1] == "" || new Date().getTime() - new Date(recentCustomGamesData[customGameId][1]).getTime() > 15552000000)
        sheet.getRange(lineRecentGames + 2 + customGameId, 1, 1, 73).setValues([["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
          "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""]]);
    }
  }
  let games = [];
  let column = 22;
  let names = [];

  let playerData = sheet.getRange(2, 1, sheet.getName() === "TRUEs" ? 20 : 15, 3).getValues();
  let puuid;
  let summonerData;
  let elo = "U";
  for (let playerId in playerData) {
    if (playerData.hasOwnProperty(playerId)) {
      puuid = playerData[playerId][1];
      // Insert new Players
      if (puuid.length < 10) {
        if (playerData[playerId][0] !== "") {
          let profileContent = response('https://euw1.api.riotgames.com/lol/summoner/v4/summoners/by-name/' + playerData[playerId][0] + apikey);
          puuid = profileContent.puuid;
          playerData[playerId][1] = profileContent.puuid;
          newPlayers.push(puuid);
        }
      } else {
        if (currentTime.getHours() === 23) {
          summonerData = response('https://euw1.api.riotgames.com/lol/summoner/v4/summoners/by-puuid/' + puuid + apikey);
          playerData[playerId][0] = summonerData.name;

          if (sheet.getName().startsWith("Tag")) column = Number(sheet.getName().substring(4));
          else if (sheet.getName() === "Scrim") column = 8;
          else {
            let scrimTeams = inputSheet.getRange(2, 12, 1, Number(inputSheet.getRange("C2:C2").getValue())).getValues()[0];
            for (let scrimTeam in scrimTeams) if (scrimTeams.hasOwnProperty(scrimTeam) && String(scrimTeams[scrimTeam]) === sheet.getName()) column = scrimTeam + 9;
          }
          //RANKED
          let rankedData = response('https://euw1.api.riotgames.com/lol/league/v4/entries/by-summoner/' + summonerData.id + apikey);
          for (let entry in rankedData) {
            if (rankedData.hasOwnProperty(entry) && rankedData[entry].queueType === "RANKED_SOLO_5x5")
              elo = String(rankedData[entry].tier).substring(0, 1) + (rankedData[entry].rank === "I" ? "1" : rankedData[entry].rank === "II" ? "2" : rankedData[entry].rank === "III"?"3":"4");
          }
          playerData[playerId][2] = elo;
        }
      }
      puuids.push(puuid);

      if (puuid !== "" && playerId < 10) {
        let turnamentGames = response("https://europe.api.riotgames.com/lol/match/v5/matches/by-puuid/" + puuid + "/ids?type=tourney&start=0&count=100&startTime=" + (parseInt((currentTime / 1000) - 15552000)) + "&" + apikey.substring(1));
        for (let turnamentGame in turnamentGames) if (turnamentGames.hasOwnProperty(turnamentGame) && !games.includes(turnamentGames[turnamentGame]) && !recentCustomGames.includes(turnamentGames[turnamentGame])) games.push(turnamentGames[turnamentGame]);

        let clashGames = response("https://europe.api.riotgames.com/lol/match/v5/matches/by-puuid/" + puuid + "/ids?startTime=" + (parseInt((currentTime / 1000) - 15552000)) +
            "&queue=700&start=0&count=100&" + apikey.substring(1));
        for (let clashGame in clashGames) if (clashGames.hasOwnProperty(clashGame) && !games.includes(clashGames[clashGame]) && !recentCustomGames.includes(clashGames[clashGame]))
          games.push(clashGames[clashGame]);
      }
      names.push(new Array(playerData[playerId][0]));
      playerData[playerId].splice(0, 1);
    }
  }
  //determineAmountofTourneyGames(playerData);
  inputSheet.getRange(4, column + 3, playerData.length, 1).setValues(names);
  sheet.getRange(2, 2, playerData.length, 2).setValues(playerData);
  return games;
}

function findPrimeLeague(games) {
  const championData = response("http://ddragon.leagueoflegends.com/cdn/" + response("http://ddragon.leagueoflegends.com/api/versions.json")[0] + "/data/en_US/champion.json");
  let startAmount = Number(sheet.getRange("B" + lineRecentGames + ":B" + lineRecentGames).getValue());
  let amount = Number(startAmount);
  let gamesArrays = [];
  let ganks = sheet.getRange("P1:R1").getValues()[0]

  for (let game in games) {
    if (games.hasOwnProperty(game)) {
      let gameId = games[game];
      let gameData = response("https://europe.api.riotgames.com/lol/match/v5/matches/" + gameId + apikey);
      let durationSeconds = Number(gameData.info.gameDuration);
      if (durationSeconds > 36000) durationSeconds = Math.round(durationSeconds / 1000);

      //determineTeam
      let team;
      let win;
      let players = gameData.info.participants;
      for (let playerId in players) {
        if (players.hasOwnProperty(playerId)) {
          let participant = players[playerId];
          if (puuids.includes(participant.puuid)) {
            team = participant.teamId;
            win = participant.win;
            break;
          }
        }
      }

      let teams = gameData.info.teams;
      let banns = [];
      let banIds = team === 200 ? (teams[1].bans).concat(teams[0].bans) : (teams[0].bans).concat(teams[1].bans);
      if (championData !== undefined) {
        let champions = championData.data;
        for (let champion in champions) if (champions.hasOwnProperty(champion))
          for (let ban in banIds) if (banIds.hasOwnProperty(ban) && banIds[ban].championId === Number(champions[champion].key)) banns.push(champions[champion].id);
      }

      let top = ["", "", "", "", "", "", "", "", "", ""];
      let jgl = ["", "", "", "", "", "", "", "", "", ""];
      let mid = ["", "", "", "", "", "", "", "", "", ""];
      let bot = ["", "", "", "", "", "", "", "", "", ""];
      let sup = ["", "", "", "", "", "", "", "", "", ""];
      let totalCS = 0;
      let supGold;
      for (let playerId in players) {
        if (players.hasOwnProperty(playerId)) {
          let participant = players[playerId];
          if (puuids.includes(participant.puuid)) totalCS += (parseInt(participant.neutralMinionsKilled) + parseInt(participant.totalMinionsKilled));
          if (participant.teamPosition === "TOP") top = determinePlayer(participant, top);
          if (participant.teamPosition === "JUNGLE") jgl = determinePlayer(participant, jgl);
          if (participant.teamPosition === "MIDDLE") mid = determinePlayer(participant, mid);
          if (participant.teamPosition === "BOTTOM") bot = determinePlayer(participant, bot);
          if (participant.teamPosition === "UTILITY") sup = determinePlayer(participant, sup);
          if (puuids.includes(participant.puuid) && participant.teamPosition === "UTILITY") supGold = participant.goldEarned;
        }
      }

      let gameDetails = response("https://europe.api.riotgames.com/lol/match/v5/matches/" + gameId + "/timeline" + apikey);
      let detailedParticipants = gameDetails.metadata.participants;
      let topId = -1;
      let jglId = -1;
      let midId = -1;
      let botId = -1;
      let supId = -1;
      for (let participant in detailedParticipants) {
        if (detailedParticipants.hasOwnProperty(participant)) {
          if (detailedParticipants[participant] === top[0]) topId = Number(participant) + 1;
          else if (detailedParticipants[participant] === jgl[0]) jglId = Number(participant) + 1;
          else if (detailedParticipants[participant] === mid[0]) midId = Number(participant) + 1;
          else if (detailedParticipants[participant] === bot[0]) botId = Number(participant) + 1;
          else if (detailedParticipants[participant] === sup[0]) supId = Number(participant) + 1;
        }
      }

      let topSoloKills = 0;
      let jglSuccessGanks = 0;
      let jglTriedGanks = 0;
      let midSoloKills = 0;
      let botMinions = 0;
      let supSuccessGanks = 0;
      let recentDamageStats = 0;
      let totalDamage = 0;
      for (let frameId in gameDetails.info.frames) {
        let events = gameDetails.info.frames[frameId].events;
        for (let eventObj in events) {
          if (events.hasOwnProperty(eventObj)) {
            let event = events[eventObj];
            let assistingIds = event.assistingParticipantIds;
            if (event.type === "CHAMPION_KILL" && assistingIds === undefined && topId > 0 && event.killerId === topId) topSoloKills++;
            if (event.type === "CHAMPION_KILL" && assistingIds === undefined && midId > 0 && event.killerId === midId) midSoloKills++;
            if (event.type === "CHAMPION_KILL" && event.timestamp < 1000000) {
              if (jglId > 0 && event.killerId === jglId) {
                if ((event.position.x - event.position.y) < -3000) {
                  ++ganks[0];
                } else if ((event.position.x - event.position.y) > 3000) {
                  ++ganks[2];
                } else {
                  ++ganks[1];
                }
                jglSuccessGanks++;
              }
              for (let ids in assistingIds)
                if (assistingIds.hasOwnProperty(ids) && jglId > 0 && assistingIds !== undefined && assistingIds[ids] === jglId) {
                  if ((event.position.x - event.position.y) < -3000) {
                    ++ganks[0];
                  } else if ((event.position.x - event.position.y) > 3000) {
                    ++ganks[2];
                  } else {
                    ++ganks[1];
                  }
                  jglSuccessGanks++;
                }
              for (let ids in assistingIds) if (assistingIds.hasOwnProperty(ids) && supId > 0 && assistingIds !== undefined && assistingIds[ids] === supId &&
                  (event.killerId === midId || event.killerId === topId)) supSuccessGanks++;
            }
            if (event.type === "CHAMPION_KILL" && event.victimId === jglId && event.timestamp < 1000000) {
              if ((event.position.x - event.position.y) < -3000) {
                ++ganks[0];
              } else if ((event.position.x - event.position.y) > 3000) {
                ++ganks[2];
              } else {
                ++ganks[1];
              }
            }
          }
        }
        let frame = gameDetails.info.frames[frameId];
        if (jglId > 0 && frameId < 16) {
          totalDamage = frame.participantFrames[jglId].damageStats.totalDamageDoneToChampions;
          if (recentDamageStats !== totalDamage) jglTriedGanks++;
        }
        if (frameId == 15 && botId > 0) botMinions = frame.participantFrames[botId].minionsKilled + frame.participantFrames[botId].jungleMinionsKilled;
        recentDamageStats = totalDamage;
      }

      top[9] = (topId === -1) ? "" : topSoloKills;
      jgl[9] = (jglId === -1) ? "" : jglSuccessGanks / jglTriedGanks;
      mid[9] = (midId === -1) ? "" : midSoloKills;
      bot[9] = (botId === -1) ? "" : botMinions;
      sup[9] = (supId === -1) ? "" : supSuccessGanks;

      let date = Utilities.formatDate(new Date(Number(gameData.info.gameCreation)), CalendarApp.getTimeZone(), 'dd.MM.YYYY HH:mm');
      let type = gameData.info.gameType === "MATCHED_GAME" ? "C" : "L";
      let totalGold = parseInt(top[6] === "" ? 0 : top[6]) + parseInt(jgl[6] === "" ? 0 : jgl[6]) + parseInt(mid[6] === "" ?
          0 : mid[6]) + parseInt(bot[6] === "" ? 0 : bot[6]) + parseInt(supGold === "" ? 0 : supGold);
      let objectives = (team === 100) ? gameData.info.teams[0].objectives : gameData.info.teams[1].objectives;
      let tower = (team === 100 ? objectives.tower.kills : objectives.tower.kills);
      let drakes = (team === 100 ? objectives.dragon.kills : objectives.dragon.kills);
      let inhibs = (team === 100 ? objectives.inhibitor.kills : objectives.inhibitor.kills);
      let heralds = (team === 100 ? objectives.riftHerald.kills : objectives.riftHerald.kills);
      let barons = (team === 100 ? objectives.baron.kills : objectives.baron.kills);
      let gameArray = [gameId, date, durationSeconds, type, win, banns[0], banns[1], banns[2], banns[3], banns[4], banns[5], banns[6], banns[7], banns[8], banns[9], top[0], top[1], top[2],
        top[3], top[4], top[5], top[6], top[7], top[8], jgl[0], jgl[1], jgl[2], jgl[3], jgl[4], jgl[5], jgl[6], jgl[7], jgl[8], mid[0], mid[1], mid[2], mid[3], mid[4], mid[5], mid[6], mid[7],
        mid[8], bot[0], bot[1], bot[2], bot[3], bot[4], bot[5], bot[6], bot[7], bot[8], sup[0], sup[1], sup[2], sup[3], sup[4], sup[5], sup[6], sup[7], sup[8], totalCS, totalGold,
        tower, drakes, inhibs, heralds, barons, top[9], jgl[9], mid[9], bot[9], sup[9]];
      if (sheet.getName() === "TRUEs") gameArray.splice(60, 0, supGold); else gameArray.push("");
      gamesArrays.push(gameArray);
      ++amount;
    }
  }

  if (gamesArrays.length > 0) {
    if (startAmount % 250 < amount % 250) sheet.getRange(lineRecentGames + 2 + (startAmount % 250), 1, gamesArrays.length, gamesArrays[0].length).setValues(gamesArrays);
    else {
      let remainingSpace = 250 - (startAmount % 250);
      let lastArray = gamesArrays.slice(remainingSpace);
      sheet.getRange(lineRecentGames + 2 + (startAmount % 250), 1, remainingSpace, gamesArrays[0].length).setValues(gamesArrays.slice(0, remainingSpace));
      sheet.getRange(lineRecentGames + 2, 1, lastArray.length, gamesArrays[0].length).setValues(lastArray);
    }
  }
  sheet.getRange("B" + lineRecentGames + ":B" + lineRecentGames).setValue(amount);
  sheet.getRange("P1:R1").setValues([ganks]);
}

// TODO CALC!A1
function findNorms() {
  let allgames = [];
  let time = Number(sheet.getRange("K1:K1").getValue());
  if (time === 0) sheet.getRange("L1:L1").setValue("init");
  let recentNumber = Number(sheet.getRange("B1:B1").getValue());
  let amount = Number(sheet.getRange("CM1:CM1").getValue());
  let init = String(sheet.getRange("L1:L1").getValue()) === "init";
  if (init) {
    if (amount > 0) {
      let initAddNorms = sheet.getRange(3, 91, amount, 1).getValues();
      for (let normId in initAddNorms) {
        let norm = initAddNorms[normId][0];
        if (initAddNorms.hasOwnProperty(normId) && !allgames.includes(norm)) {
          allgames.push(norm);
        }
      }
    } else allgames = addPlayersGames(puuids, allgames);

    console.log(allgames.length);
  } else {
    if (time < parseInt((currentTime / 1000) - 15552000)) time = parseInt((currentTime / 1000) - 15552000)
    for (let puuid in puuids) {
      if (puuids.hasOwnProperty(puuid) && puuids[puuid] !== "" && puuids[puuid] !== undefined) {
        let games40 = response("https://europe.api.riotgames.com/lol/match/v5/matches/by-puuid/" + puuids[puuid] + "/ids?startTime=" +time+"&queue=400&start=0&count=100&"+apikey.substring(1));
        for (let game in games40) if(games40.hasOwnProperty(game) && !allgames.includes(games40[game]) && Number(String(games40[game]).substring(5))>recentNumber) allgames.push(games40[game]);
        let games42 = response("https://europe.api.riotgames.com/lol/match/v5/matches/by-puuid/" + puuids[puuid] + "/ids?startTime=" +time+"&queue=420&start=0&count=100&"+apikey.substring(1));
        for (let game in games42) if(games42.hasOwnProperty(game) && !allgames.includes(games42[game]) && Number(String(games42[game]).substring(5))>recentNumber) allgames.push(games42[game]);
        let games44 = response("https://europe.api.riotgames.com/lol/match/v5/matches/by-puuid/" + puuids[puuid] + "/ids?startTime=" +time+"&queue=440&start=0&count=100&"+apikey.substring(1));
        for (let game in games44) if(games44.hasOwnProperty(game) && !allgames.includes(games44[game]) && Number(String(games44[game]).substring(5))>recentNumber) allgames.push(games44[game]);
      }
    }
  }

  for (let game in allgames) if (Number(allgames[game].substring(5)) < recentNumber) allgames.splice(game, 1);
  if (newPlayers.length > 0 && !init) allgames = addPlayersGames(newPlayers, allgames);
  allgames.sort();
  console.info(sheet.getName() + ": " + ((allgames.length === 0) ? "No more matches " : allgames.length + " new matches"));
  if (allgames.length > 0) {
    let initNormsArray = [];
    for (let i = 0; i < allgames.length; ++i) initNormsArray.push("");

    if (init && allgames.length > 0) {
      for (let normId in allgames) if (allgames.hasOwnProperty(normId)) initNormsArray[normId] = [allgames[normId]];
      sheet.getRange(3, 91, initNormsArray.length, 1).setValues(initNormsArray);
    }
    for (let game in allgames) {
      let gameContent = response("https://europe.api.riotgames.com/lol/match/v5/matches/" + allgames[game] + apikey);
      if (response !== undefined && gameContent !== undefined) performGame(gameContent, gameContent.info.participants);
      else console.error(allgames[game] + " skipped");
    }
    if (normsInSection.length > 0) sheet.getRange(sectionLine, sectionRow, normsInSection.length, 16).setValues(normsInSection);
    sheet.getRange("K1:K1").setValue(parseInt(Number(currentTime.getTime()) / 1000));
    if (init) {
      for (let normId in allgames) if (allgames.hasOwnProperty(normId)) initNormsArray[normId] = [allgames[normId]];
      sheet.getRange(3, 91, initNormsArray.length, 1).setValues(initNormsArray);
      console.log("OUT");
    }
  }

  if (init) sheet.getRange("L1:L1").setValue("");
}

function performGame(game, players) {
  let timestamp = Number(game.info.gameCreation);
  let sectionNew = (parseInt((new Date(timestamp).getTime() - new Date('June 16, 2021 00:00:00 +0000').getTime()) / 864000000)) % 20 + 1;
  if (sectionNew !== section) {
    if (normsInSection.length > 0) sheet.getRange(sectionLine, sectionRow, normsInSection.length, 16).setValues(normsInSection);
    normsInSection = [];
    section = sectionNew;
    let sectionRowBig = (section === 1) ? (section + 3) : (section + 4);
    sectionRow = (sectionRowBig % 5 === 4) ? 74 : (sectionRowBig % 5 * 17 + 1);
    sectionLine = sheet.getRange("BL" + (300 + section) + ":BL" + (300 + section)).getValue() + (parseInt(sectionRowBig / 5) * 500) + 1;
  }

  let duration = game.info.gameDuration;
  let matchId = game.metadata.matchId;
  let date = Utilities.formatDate(new Date(timestamp), CalendarApp.getTimeZone(), 'dd.MM.YYYY HH:mm');
  for (let playerId in players) {
    if (players.hasOwnProperty(playerId)) {
      let participant = players[playerId];
      if (puuids.includes(participant.puuid)) {
        let lane = participant.teamPosition;
        let puuid = participant.puuid;
        let champion = participant.championName;
        let enemy = "";
        let win = participant.win;
        let cs = (participant.neutralMinionsKilled + participant.totalMinionsKilled) * 60 / ((duration > 10000) ? (duration / 1000) : duration);
        cs = Math.round(cs * 10) / 10;
        let gold = participant.goldEarned;
        let egold = 0;
        for (let enemyPlayer in players) {
          if (players.hasOwnProperty(enemyPlayer)) {
            let counterpart = players[enemyPlayer];
            if (counterpart.teamPosition === lane && counterpart.puuid !== puuid) {
              enemy = counterpart.championName;
              egold = counterpart.goldEarned;
              break;
            }
          }
        }
        let gdiff = (egold > 0) ? gold - egold : 0;
        let gpm = parseInt(gold * 60 / ((duration > 10000) ? (duration / 1000) : duration));
        let ad = participant.physicalDamageDealtToChampions;
        let ap = participant.magicDamageDealtToChampions;
        let td = participant.trueDamageDealtToChampions;
        let taken = participant.totalDamageTaken;
        let healed = participant.totalHeal;
        let cc = participant.timeCCingOthers;
        normsInSection.push([matchId, date, lane, puuid, champion, enemy, win, cs, gdiff, gpm, ad, ap, td, taken, healed, cc]);
      }
    }
  }
  sheet.getRange("B1:B1").setValue(matchId.substring(5));
}

function fetchResponses(puuid, epoch) {
  let matchIds = [];
  let contentEpoch = fetchresponse(puuid, epoch, "400");
  for (let matchId in contentEpoch) if (contentEpoch.hasOwnProperty(matchId) && !matchIds.includes(contentEpoch[matchId])) matchIds.push(contentEpoch[matchId]);
  contentEpoch = fetchresponse(puuid, epoch, "420");
  for (let matchId in contentEpoch) if (contentEpoch.hasOwnProperty(matchId) && !matchIds.includes(contentEpoch[matchId])) matchIds.push(contentEpoch[matchId]);
  contentEpoch = fetchresponse(puuid, epoch, "440");
  for (let matchId in contentEpoch) if (contentEpoch.hasOwnProperty(matchId) && !matchIds.includes(contentEpoch[matchId])) matchIds.push(contentEpoch[matchId]);
  return matchIds;
}

function fetchresponse(puuid, epoch, queueId) {
  return response("https://europe.api.riotgames.com/lol/match/v5/matches/by-puuid/" + puuid + "/ids?startTime=" + (parseInt(currentTime / 1000) - (3000000 * epoch)) + "&endTime=" +
      (parseInt(currentTime / 1000) - (3000000 * (epoch - 1))) + "&queue=" + queueId + "&start=0&count=100&" + apikey.substring(1));
}

function determinePlayer(participant, array) {
  return puuids.includes(participant.puuid) ? [participant.puuid, participant.championName, array[2], participant.kills, participant.deaths, participant.assists, (participant.teamPosition ===
      "UTILITY") ? participant.visionScore : participant.goldEarned, (participant.teamPosition === "UTILITY") ? participant.visionWardsBoughtInGame : participant.totalDamageDealtToChampions,
    array[8], array[9]] : [array[0], array[1], participant.championName, array[3], array[4], array[5], array[6], array[7], participant.goldEarned, array[9]];
}

function addPlayersGames(puuids, allgames) {
  console.log("Load " + puuids);
  for (let puuid in puuids) {
    if (puuids.hasOwnProperty(puuid)) {
      for (let epochId = 1; epochId < 11; ++epochId) {
        let contentEpoch = fetchResponses(puuids[puuid], epochId);
        for (let matchId in contentEpoch) if (!allgames.includes(contentEpoch[matchId])) allgames.push(contentEpoch[matchId]);
      }
    }
  }
  return allgames;
}

function determineAmountofTourneyGames(playerData) {
  let alltourneygamesAmountArray = [];
  for (let playerId in playerData) {
    if (playerData.hasOwnProperty(playerId)) {
      let puuid = playerData[playerId][1];
      alltourneygamesAmountArray.push((puuid.length > 10) ? ([response("https://europe.api.riotgames.com/lol/match/v5/matches/by-puuid/" + puuid + "/ids?type=tourney&start=0&count=100&" + apikey.substring(1)).length]) : ([0]));
    }
  }
  sheet.getRange(2, 21, playerData.length, 1).setValues(alltourneygamesAmountArray);
}

Body:
The cause of the error is that you are calling sheet too many times, and each call is a request which takes time to process and ultimately leads to the timeout. The easy sounding solution is reduce the calls of sheet.getRange() and sheet.setValue() and sheet.getName() etc… so that you ideally do them once per each sheet you are working on. A simple example would be as follows, where everything is done once (except the api call, which ideally should also be done using a bulk api).

function writePlayersApiResToSheet( sheet ){
  // get all players data from the sheet in only 1 call
  const allPlayers = sheet.getDataRange().getValues()

  // remove the header in row 1
  allPlayers.shift()

  // api responses will be pushed here
  const output = []

  // do something, like call the api for each user
  allPlayers.forEach( player=> output.push([getPlayerInfoFromApi(player)]) )

  // write to the sheet once
  const startRow = 2
  const startCol = 10 // or wherever the api res should go
  sheet.getRange( startRow, startCol, allPlayers.length, 1).setValues( output )
}

Google provides this Documentation on this topics.


来源: stackexchange

问:
Python 3 while loop can't show list keys?
Ok so i am trying to do some basic while loop to show text formated in this way:

A - 80%-100%

B - 60%-80%

C - 50-60%

D - less then 50%

with this code:

```<code>dictionary={'A':'80%-100%','B':'60%-80%','C':'50-60%','D':'less then 50%'}
klucze=list(dictionary.keys())
q=0
while q<4:
print(klucze[q]," - ",dictionary[q])
q+=1
</code>```

It's working with klucze[q] only, but when i try to print dictionary[q] too, i get the error

答:
Instead of doing complicated things, use dict.items() method that returns dictionary key-value.

```<code>dct = {'A':'80%-100%','B':'60%-80%','C':'50-60%','D':'less then 50%'}

for k, v in dct.items():
    print(k, '-', v)
</code>```

Output:

```<code>A - 80%-100%
B - 60%-80%
C - 50-60%
D - less then 50%
</code>```

ContentLicense: CC BY-SA 4.0

Body:
Ok so i am trying to do some basic while loop to show text formated in this way:

A - 80%-100%

B - 60%-80%

C - 50-60%

D - less then 50%

with this code:

dictionary={'A':'80%-100%','B':'60%-80%','C':'50-60%','D':'less then 50%'}
klucze=list(dictionary.keys())
q=0
while q<4:
print(klucze[q]," - ",dictionary[q])
q+=1

It's working with klucze[q] only, but when i try to print dictionary[q] too, i get the error

Body:
Instead of doing complicated things, use dict.items() method that returns dictionary key-value.

dct = {'A':'80%-100%','B':'60%-80%','C':'50-60%','D':'less then 50%'}

for k, v in dct.items():
    print(k, '-', v)

Output:

A - 80%-100%
B - 60%-80%
C - 50-60%
D - less then 50%


问:
How to Access RDS Proxy from a Different AWS Region?
I have a RDS database and a RDS proxy in one region.

However, I also have a lambda function in a different region that need to connect to the RDS proxy in the first region.

I know that the RDS proxy can't be publicly accessible and need to be within the same VPC as the instance trying to connect to it.

Is there a way to allow a lambda function to connect to a RDS proxy in a different region?

I know that an RDS DB can be publicly accessible, however I was getting sql timeout errors in my lambda functions, which is why I chose to use a RDS proxy.

答:
I know that the RDS proxy can't be publicly accessible and need to be
within the same VPC as the instance trying to connect to it.

I think the part in bold is partially incorrect. The RDS proxy has to be in the same VPC as the RDS database. As far as I can tell, the instance trying to connect doesn't need to be in the same VPC, I think it could also be in a peered VPC.

To answer your question, I would suggest placing the Lambda function in a VPC in the other region, and create a VPC peering connection between the two VPCs.


问:
StringBuilder.Append Vs StringBuilder.AppendFormat
I was wondering about StringBuilder and I've got a question that I was hoping the community would be able to explain.

Let's just forget about code readability, which of these is faster and why?

StringBuilder.Append:

```<code>StringBuilder sb = new StringBuilder();
sb.Append(string1);
sb.Append("----");
sb.Append(string2);
</code>```

StringBuilder.AppendFormat:

```<code>StringBuilder sb = new StringBuilder();
sb.AppendFormat("{0}----{1}",string1,string2);
</code>```

答: I'd assume it was the call that did the least amount of work. Append just concatenates strings, where AppendFormat is doing string substitutions. Of course these days, you never can tell...</p>

OwnerDisplayName: Sergio

ContentLicense: CC BY-SA 2.5

Body:
I was wondering about StringBuilder and I've got a question that I was hoping the community would be able to explain.

Let's just forget about code readability, which of these is faster and why?

StringBuilder.Append:

StringBuilder sb = new StringBuilder();
sb.Append(string1);
sb.Append("----");
sb.Append(string2);

StringBuilder.AppendFormat:

StringBuilder sb = new StringBuilder();
sb.AppendFormat("{0}----{1}",string1,string2);

LastEditorDisplayName: Samuel

OwnerDisplayName: Paul W Homer


问:
How can I pair device to Android Studio Bumblebee using Wi-Fi?
I want to debug my app via the last release of Android Studio Bumblebee using Wi-Fi (without wire connecting). How can I do it?</p>

答:
First, make sure that your device has Android version 11+. Android Studio Bumblebee supports the wireless debugging feature on Android 11 and higher devices.

Secondly, make sure that you use the last release of Android Studio https://developer.android.com/studio?utm_source=android-studio

Then

Open available devices menu

Choose Pair devices Using Wi-Fi and you can see QR-code which you can scan via your phone

Go to device settings: System -> Developer options -> Wireless debugging -> Pair device with QR code

Scan QR code using the device camera. Wait several seconds. Your device must be paired

If developer options isn't available on your device settings then activate it first, see https://developer.android.com/studio/debug/dev-options

1.
2.
3.


问:
Using split in python script correctly
Im making a program that parses .m file into .h file with rearanging some stuff in different order. Im basically new to Python, but I know other language. Program code is:

```<code> with open('D:\\\toolchain\Simulink\data\\application_parameters_data.m','r') as InputFile:
            for j in InputFile:
                for k in range(2): InputFile.readline()
                with open('D:\\\toolchain\Connector\ConDataGenerated.h', 'w') as file1:
                    t1 = Template('$datatype $name $initValue $comment')
                    for i in InputFile:
                        file1.write("\n")
                        Type = [name.strip() for name in i.split(';\n')[0].split(',')]
                        file1.write(t1.safe_substitute(datatype = Type[5], name = Type[0], initValue =Type[1], comment =Type[4]))
</code>```

I need to change it contence divided by , between elements and ; between lines accordingly. Example of input code:

```<code>'ManCtrlInputShaftSpeedSwt', 0, [0 1], '', 'comment', 'uint16';
'ManCtrlInputShaftSpeedPar', 0, [0 1], '', 'comment', 'single';
'ManCtrlInputShaftSpeed1Swt', 0, [0 1], '', 'comment', 'uint16';
'ManCtrlInputShaftSpeed1Par', 0, [0 1], '', 'comment', 'single';
'ManCtrlInputShaftSpeed2Swt', 0, [0 1], '', 'comment', 'uint16';
'ManCtrlInputShaftSpeed2Par', 0, [0 1], '', 'comment', 'single';
'ManCtrlOutputShaftSpeedSwt', 0, [0 1], '', 'comment', 'uint16';
'ManCtrlOutputShaftSpeedPar', 0, [0 1], '', 'comment', 'single';
'ManCtrlOutputShaftSpeedDirnSwt', 0, [0 1], '', 'comment', 'uint16';
'ManCtrlOutputShaftSpeedDirnPar', 0, [0 1], '', 'comment', 'uint16';

'ManCtrlMeasPositionS1Swt', 0, [0 1], '', 'comment', 'uint16';
'ManCtrlMeasPositionS1Par', 0, [0 1], '', 'comment', 'single';
</code>```

Here's the thing. Script works fine until it hits the space between strings or something that it doesnt recognise, or, it works with writing only first element of string to new file, in that case it iterates through strings without problems. I think it somehow connected to compiler telling me next:

```<code>Traceback (most recent call last):
  File "D:\\StringTemplate.py", line 16, in <module>
    file1.write(t1.safe_substitute(datatype = Type[5], name = Type[0], initValue =Type[1], comment =Type[4]))
IndexError: list index out of range
</code>```

even though file creates with this problems. example of output code:

```<code>'uint16' 'ManCtrlInputShaftSpeedSwt' 0 'comment'
'single' 'ManCtrlInputShaftSpeedPar' 0 'comment'
'uint16' 'ManCtrlInputShaftSpeed1Swt' 0 'comment'
'single' 'ManCtrlInputShaftSpeed1Par' 0 'comment'
'uint16' 'ManCtrlInputShaftSpeed2Swt' 0 'comment'
'single' 'ManCtrlInputShaftSpeed2Par' 0 'comment'
'uint16' 'ManCtrlOutputShaftSpeedSwt' 0 'comment'
'single' 'ManCtrlOutputShaftSpeedPar' 0 'comment'
'uint16' 'ManCtrlOutputShaftSpeedDirnSwt' 0 'comment'
'uint16' 'ManCtrlOutputShaftSpeedDirnPar' 0 'comment'
</code>```

What should I do?

答:
You can add a condition to check if the line has a length of 5 / if it's not empty, something like:

                        Type = [name.strip() for name in i.split(';\n')[0].split(',')]
                        if len(Type) > 5:
                            file1.write(t1.safe_substitute(datatype = Type[5], name = Type[0], initValue =Type[1], comment =Type[4]))
```

Title: Using split in python script correctly

Body:
Im making a program that parses .m file into .h file with rearanging some stuff in different order. Im basically new to Python, but I know other language. Program code is:

 with open('D:\\\toolchain\Simulink\data\\application_parameters_data.m','r') as InputFile:
            for j in InputFile:
                for k in range(2): InputFile.readline()
                with open('D:\\\toolchain\Connector\ConDataGenerated.h', 'w') as file1:
                    t1 = Template('$datatype $name $initValue $comment')
                    for i in InputFile:
                        file1.write("\n")
                        Type = [name.strip() for name in i.split(';\n')[0].split(',')]
                        file1.write(t1.safe_substitute(datatype = Type[5], name = Type[0], initValue =Type[1], comment =Type[4]))

I need to change it contence divided by , between elements and ; between lines accordingly. Example of input code:

'ManCtrlInputShaftSpeedSwt', 0, [0 1], '', 'comment', 'uint16';
'ManCtrlInputShaftSpeedPar', 0, [0 1], '', 'comment', 'single';
'ManCtrlInputShaftSpeed1Swt', 0, [0 1], '', 'comment', 'uint16';
'ManCtrlInputShaftSpeed1Par', 0, [0 1], '', 'comment', 'single';
'ManCtrlInputShaftSpeed2Swt', 0, [0 1], '', 'comment', 'uint16';
'ManCtrlInputShaftSpeed2Par', 0, [0 1], '', 'comment', 'single';
'ManCtrlOutputShaftSpeedSwt', 0, [0 1], '', 'comment', 'uint16';
'ManCtrlOutputShaftSpeedPar', 0, [0 1], '', 'comment', 'single';
'ManCtrlOutputShaftSpeedDirnSwt', 0, [0 1], '', 'comment', 'uint16';
'ManCtrlOutputShaftSpeedDirnPar', 0, [0 1], '', 'comment', 'uint16';

'ManCtrlMeasPositionS1Swt', 0, [0 1], '', 'comment', 'uint16';
'ManCtrlMeasPositionS1Par', 0, [0 1], '', 'comment', 'single';

Here's the thing. Script works fine until it hits the space between strings or something that it doesnt recognise, or, it works with writing only first element of string to new file, in that case it iterates through strings without problems. I think it somehow connected to compiler telling me next:

Traceback (most recent call last):
  File "D:\\StringTemplate.py", line 16, in <module>
    file1.write(t1.safe_substitute(datatype = Type[5], name = Type[0], initValue =Type[1], comment =Type[4]))
IndexError: list index out of range

even though file creates with this problems. example of output code:

'uint16' 'ManCtrlInputShaftSpeedSwt' 0 'comment'
'single' 'ManCtrlInputShaftSpeedPar' 0 'comment'
'uint16' 'ManCtrlInputShaftSpeed1Swt' 0 'comment'
'single' 'ManCtrlInputShaftSpeed1Par' 0 'comment'
'uint16' 'ManCtrlInputShaftSpeed2Swt' 0 'comment'
'single' 'ManCtrlInputShaftSpeed2Par' 0 'comment'
'uint16' 'ManCtrlOutputShaftSpeedSwt' 0 'comment'
'single' 'ManCtrlOutputShaftSpeedPar' 0 'comment'
'uint16' 'ManCtrlOutputShaftSpeedDirnSwt' 0 'comment'
'uint16' 'ManCtrlOutputShaftSpeedDirnPar' 0 'comment'

What should I do?


问:
Error: The apk for your currently selected variant (Unknown output) is not signed. Please specify a signing configuration for this variant (debug)
After upgrading to Android Studio Arctic Fox (2020.3.1) Canary 9. I cannot run my tests. It pops up the Edit Configurations window to show Error: The app for your currently selected variant (Unknown output) is not signed. Please specify a signing configuration for this variant (debug). message. I can't seem to solve this issue just by creating .jks and using the release signing configuration for debug variant as well like most of the posts suggested. I'm kinda stuck between whether I downgrade or try to solve it somehow. Is there anyone who faced this issue before? Any suggestions and opinions are welcomed.

Problem still occurs in Android Studio Arctic Fox (2020.3.1) Canary 10 version as well.

答:
What worked for me was to add the following on the app level build.gradle (For the 'release' variant in this example):</p>
```<code>
android{

   signingConfigs {
       release {
           storeFile file("path to your keystore file")
           storePassword "your store password "
           keyAlias "your keystore alias"
           keyPassword "your key password"
       }
   }

   buildTypes {
       release {
           ...
           ...
           signingConfig signingConfigs.release
       }
   }

}
</code>```

Body:
What worked for me was to add the following on the app level build.gradle (For the 'release' variant in this example):

android{

   signingConfigs {
       release {
           storeFile file("path to your keystore file")
           storePassword "your store password "
           keyAlias "your keystore alias"
           keyPassword "your key password"
       }
   }

   buildTypes {
       release {
           ...
           ...
           signingConfig signingConfigs.release
       }
   }

}


问:
Maven clean compile does not work
I have maven-compiler-plugin in my pom file as follows but compiler get angry with generic parameters. my maven version is "Apache Maven 3.0.3 (r1075438; 2011-02-28 19:31:09+0200)"

```<code><plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.3.2</version>
    <configuration>
        <source>1.6</source>
        <target>1.6</target>
        <compilerVersion>1.6</compilerVersion>
    </configuration>
</plugin>
</code>```

and the class which compiler get angry is as follows

```<code>List<EulTransactionHistory> list = hibernateTemplate.findByCriteria(criteria, -1, 1);
EulTransactionHistory existingRecord = DBUtils.oneAndOnlyOne(list);
</code>```

and the spec for DBUtils.oneAndOnlyOne is as follows

```<code>public static <T> T oneAndOnlyOne(List<T> list) {...}
</code>```

finally the exception is

```<code>Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.3.2:compile (default-compile) on project etlscheduler: Compilation failure: Compilation failure SchedulerDaoImpl.java:[329,18] incompatible types
found   : java.lang.Object
required: com.aric.etlscheduler.domain.EulTransactionHistory
</code>```

Moreover when I compile this project with eclipse it compiles sucessfully.

答:
From the compiler error, it looks like this is possibly what is happening.

DBUtils.oneAndOnlyOne(list) is returning Object instead of EulTransactionHistory.

This is because the list which is passed to the method is a list of Objects and not a list of EulTransactionHistory.

This, in turn, is because hibernateTemplate.findByCriteria() is returning a list of Objects and not a list of EulTransactionHistory.

ContentLicense: CC BY-SA 3.0

Title: Maven clean compile does not work

Body:
I have maven-compiler-plugin in my pom file as follows but compiler get angry with generic parameters. my maven version is "Apache Maven 3.0.3 (r1075438; 2011-02-28 19:31:09+0200)"

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.3.2</version>
    <configuration>
        <source>1.6</source>
        <target>1.6</target>
        <compilerVersion>1.6</compilerVersion>
    </configuration>
</plugin>

and the class which compiler get angry is as follows

List<EulTransactionHistory> list = hibernateTemplate.findByCriteria(criteria, -1, 1);
EulTransactionHistory existingRecord = DBUtils.oneAndOnlyOne(list);

and the spec for DBUtils.oneAndOnlyOne is as follows

public static <T> T oneAndOnlyOne(List<T> list) {...}

finally the exception is

Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.3.2:compile (default-compile) on project etlscheduler: Compilation failure: Compilation failure SchedulerDaoImpl.java:[329,18] incompatible types
found   : java.lang.Object
required: com.aric.etlscheduler.domain.EulTransactionHistory

Moreover when I compile this project with eclipse it compiles sucessfully.


问:
Java ActiveMQ + STOMP + SSH: illegal reflective access operation to method sun.security.ssl.SSLSocketImpl.setHost
I'm writing a simple Java JMS QueueBrowser client to AmazonMQ, that runs ActiveMQ with stomp protocol over ssh (hence he transport is stomp+ssl:

```<code>// java
import java.util.Enumeration;

// jms
import javax.jms.IllegalStateException;
import javax.jms.JMSException;
import javax.jms.Queue;
import javax.jms.QueueBrowser;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.ConnectionFactory;
import javax.jms.Connection;

// activemq
import org.apache.activemq.ActiveMQConnectionFactory;

public class QueueBrowserExample {
    public static void main(String[] args) throws Exception {

        System.out.println("init");
        try {

            final String PORT = "61616";
            final String PROTOCOL = "stomp+ssl";
            final String HOST = "xxx.mq.us-east-1.amazonaws.com";
            final String connectionString = PROTOCOL + "://" + HOST + ":" + PORT;

            System.out.println("attempt to connect to " + connectionString);

            ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(connectionString);
            Connection connection = connectionFactory.createConnection("admin", "admin");
            connection.start();
            Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            Queue queue = session.createQueue("Test");
            QueueBrowser queueBrowser = session.createBrowser(queue);
            Enumeration msgs = queueBrowser.getEnumeration();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
</code>```

I'm getting then a javax.jms.JMSException execepion due to the Transport used (stomp+ssl I assume)

```<code>javax.jms.JMSException: Could not create Transport. Reason: java.lang.IllegalArgumentException: Invalid connect parameters: {wireFormat.host=b-02b566af-1f0d-4d48-ad24-229a813a53fb-1.mq.us-east-1.amazonaws.com}
        at org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:36)
        at org.apache.activemq.ActiveMQConnectionFactory.createTransport(ActiveMQConnectionFactory.java:319)
        at org.apache.activemq.ActiveMQConnectionFactory.createActiveMQConnection(ActiveMQConnectionFactory.java:332)
        at org.apache.activemq.ActiveMQConnectionFactory.createConnection(ActiveMQConnectionFactory.java:253)
        at QueueBrowserExample.main(QueueBrowserExample.java:37)
Caused by: java.lang.IllegalArgumentException: Invalid connect parameters: {wireFormat.host=b-02b566af-1f0d-4d48-ad24-229a813a53fb-1.mq.us-east-1.amazonaws.com}
        at org.apache.activemq.transport.TransportFactory.doConnect(TransportFactory.java:122)
        at org.apache.activemq.transport.TransportFactory.connect(TransportFactory.java:64)
        at org.apache.activemq.ActiveMQConnectionFactory.createTransport(ActiveMQConnectionFactory.java:317)
        ... 3 more
</code>```

The ActiveMQ back-end is using STOMP, and I do not have any access to it. Hence I have to figure how to "manage" the queue (watching messages only, not processing), and I came to QueueBrowser and JMS.

答:
JMS over STOMP is not supported.

Keep in mind that JMS is just an API. The underlying wire protocol is different between most brokers. In ActiveMQ "Classic" (which is what Amazon MQ uses) you can use JMS via the OpenWire protocol or via AMQP (which requires using Qpid JMS library). There is no support for JMS over STOMP.

In this case, you're using the OpenWire JMS client since you're using org.apache.activemq.ActiveMQConnectionFactory. It doesn't matter what you specify in the connection string, the client will use the OpenWire protocol.

STOMP just doesn't support much of the functionality exposed by JMS. Queue browsers in particular are not supported by STOMP.

Body:
I'm writing a simple Java JMS QueueBrowser client to AmazonMQ, that runs ActiveMQ with stomp protocol over ssh (hence he transport is stomp+ssl:

// java
import java.util.Enumeration;

// jms
import javax.jms.IllegalStateException;
import javax.jms.JMSException;
import javax.jms.Queue;
import javax.jms.QueueBrowser;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.ConnectionFactory;
import javax.jms.Connection;

// activemq
import org.apache.activemq.ActiveMQConnectionFactory;

public class QueueBrowserExample {
    public static void main(String[] args) throws Exception {

        System.out.println("init");
        try {

            final String PORT = "61616";
            final String PROTOCOL = "stomp+ssl";
            final String HOST = "xxx.mq.us-east-1.amazonaws.com";
            final String connectionString = PROTOCOL + "://" + HOST + ":" + PORT;

            System.out.println("attempt to connect to " + connectionString);

            ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(connectionString);
            Connection connection = connectionFactory.createConnection("admin", "admin");
            connection.start();
            Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            Queue queue = session.createQueue("Test");
            QueueBrowser queueBrowser = session.createBrowser(queue);
            Enumeration msgs = queueBrowser.getEnumeration();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

I'm getting then a javax.jms.JMSException execepion due to the Transport used (stomp+ssl I assume)

javax.jms.JMSException: Could not create Transport. Reason: java.lang.IllegalArgumentException: Invalid connect parameters: {wireFormat.host=b-02b566af-1f0d-4d48-ad24-229a813a53fb-1.mq.us-east-1.amazonaws.com}
        at org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:36)
        at org.apache.activemq.ActiveMQConnectionFactory.createTransport(ActiveMQConnectionFactory.java:319)
        at org.apache.activemq.ActiveMQConnectionFactory.createActiveMQConnection(ActiveMQConnectionFactory.java:332)
        at org.apache.activemq.ActiveMQConnectionFactory.createConnection(ActiveMQConnectionFactory.java:253)
        at QueueBrowserExample.main(QueueBrowserExample.java:37)
Caused by: java.lang.IllegalArgumentException: Invalid connect parameters: {wireFormat.host=b-02b566af-1f0d-4d48-ad24-229a813a53fb-1.mq.us-east-1.amazonaws.com}
        at org.apache.activemq.transport.TransportFactory.doConnect(TransportFactory.java:122)
        at org.apache.activemq.transport.TransportFactory.connect(TransportFactory.java:64)
        at org.apache.activemq.ActiveMQConnectionFactory.createTransport(ActiveMQConnectionFactory.java:317)
        ... 3 more

The ActiveMQ back-end is using STOMP, and I do not have any access to it. Hence I have to figure how to "manage" the queue (watching messages only, not processing), and I came to QueueBrowser and JMS.


问:
Sql order by, want to sort alphabetically if number are same
I'm trying to sort an employee table, but if salary of two employees is same, I want to sort them alphabetically. How do I do this. I want sort alphabetically only in case salaries are same.</p>

答:
You just add the next column:

 SELECT * FROM employees ORDER BY salary, name;
```


问:
My html code don't load FontAwesome icons, png image and google fonts
I started a project to learn HTML, CSS and JavaScript and coded a full HTML page but my navigator doesn't load images, FontAwesome icons, and it doesn't apply my css file (tried on Brave and Microsoft Edge navigator).

I removed the most part of the code, I just left the CSS and header of my code - Any ideas of what is causing me trouble?

* {
    box-sizing: border-box;
    font-family: 'Raleway', sans-serif;
    background-color: #F2F2F2;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="preconnect" href="https://fonts.googleapis.com">
        <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
        <link href="https://fonts.googleapis.com/css2?family=Raleway:wght@100&display=swap" rel="stylesheet">
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.15.4/css/fontawesome.min.css" integrity="sha384-jLKHWM3JRmfMU0A5x5AkjWkw/EYfGUAGagvnfryNV3F9VqM98XiIH7VBGVoxVSc7" crossorigin="anonymous">
        <link href="/css/style.css">
        <link href="/css/normalize.css">
        <title>Booki</title>
        <nav>
            Hébergement
            Activités
        <nav>
        <img src="/assets/logo/Booki.png">
    </head>
</html></code>```

UPDATE:
I found how to display the path wasn't correct,i just need to remove the slash at the start of the path, and it works !

答:
Use body tag to render your content on the page

```<code> <!DOCTYPE html>
<html>
    <head>
        ...
        <title>Booki</title>
    </head>
<body>
       <nav>
            <a class="nav" href="#">Hébergement</a>
            <a class="nav" href="#">Activités</a>
        <nav>
        <a href="#"><img src="/assets/logo/Booki.png"></a>
</body>
</html>
</code>```

Body:
I started a project to learn HTML, CSS and JavaScript and coded a full HTML page but my navigator doesn't load images, FontAwesome icons, and it doesn't apply my css file (tried on Brave and Microsoft Edge navigator).

I removed the most part of the code, I just left the CSS and header of my code - Any ideas of what is causing me trouble?

* {
    box-sizing: border-box;
    font-family: 'Raleway', sans-serif;
    background-color: #F2F2F2;
}

<!DOCTYPE html>

        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="preconnect" href="https://fonts.googleapis.com">
        <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
        <link href="https://fonts.googleapis.com/css2?family=Raleway:wght@100&display=swap" rel="stylesheet">
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.15.4/css/fontawesome.min.css" integrity="sha384-jLKHWM3JRmfMU0A5x5AkjWkw/EYfGUAGagvnfryNV3F9VqM98XiIH7VBGVoxVSc7" crossorigin="anonymous">
        <link href="/css/style.css">
        <link href="/css/normalize.css">
        <title>Booki</title>

            Hébergement
            Activités

UPDATE:
I found how to display the path wasn't correct,i just need to remove the slash at the start of the path, and it works !

Body:
Use body tag to render your content on the page

 <!DOCTYPE html>
<html>
    <head>
        ...
        <title>Booki</title>
    </head>
<body>
       <nav>
            <a class="nav" href="#">Hébergement</a>
            <a class="nav" href="#">Activités</a>
        <nav>
        <a href="#"><img src="/assets/logo/Booki.png"></a>
</body>
</html>


问:
Facebook login in fragment in android
I'm trying to login Facebook using custom interface it worked fine in Activity class. same thing i have to do in Fragment too. but Callback is not executing. is it not possible to add CallbackResult in Fragment's OnActivityResult ??</p>

答:
Initialize CallbackManager in your activity

Declare variable

```<code>lateinit var callbackManager: CallbackManager
</code>```

create it in Oncreate

```<code>override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    callbackManager = CallbackManager.Factory.create()
}
</code>```

in your onActivityResult method, call callbackManager.onActivityResult to pass the login results to the LoginManager via callbackManager

```<code> override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    callbackManager.onActivityResult(requestCode, resultCode, data)
}
</code>```

In yout fragment no need to call onActivityResult again just do this

```<code>class MyFragment : Fragment() {

  lateinit var callbackManager: CallbackManager

  override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        callbackManager = (activity as MainActivity).callbackManager

        LoginManager.getInstance()
        .registerCallback(callbackManager,
            object : FacebookCallback<LoginResult?> {
                override fun onSuccess(result: LoginResult?) {

                }

                override fun onCancel() {
                    Toast.makeText(context, "Login Cancelled", Toast.LENGTH_LONG).show()
                }

                override fun onError(error: FacebookException) {
                    Toast.makeText(context, error.message, Toast.LENGTH_LONG).show()
                }
            })

  }

}
</code>```

Title: Facebook login in fragment in android

Body:
Initialize CallbackManager in your activity

Declare variable

lateinit var callbackManager: CallbackManager

create it in Oncreate

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    callbackManager = CallbackManager.Factory.create()
}

in your onActivityResult method, call callbackManager.onActivityResult to pass the login results to the LoginManager via callbackManager

 override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    callbackManager.onActivityResult(requestCode, resultCode, data)
}

In yout fragment no need to call onActivityResult again just do this

class MyFragment : Fragment() {

  lateinit var callbackManager: CallbackManager

  override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        callbackManager = (activity as MainActivity).callbackManager

        LoginManager.getInstance()
        .registerCallback(callbackManager,
            object : FacebookCallback<LoginResult?> {
                override fun onSuccess(result: LoginResult?) {

                }

                override fun onCancel() {
                    Toast.makeText(context, "Login Cancelled", Toast.LENGTH_LONG).show()
                }

                override fun onError(error: FacebookException) {
                    Toast.makeText(context, error.message, Toast.LENGTH_LONG).show()
                }
            })

  }

}


问:
Uncaught SyntaxErrror: Unexpected token ILLEGAL in chrome
I'm having a problem within the jQuery ajax function. The following code works fine in Mozilla but doesn't work in IE or Chrome, when I try to identify the problem using Developer Tools in chrome I get the error:

```<code>Uncaught SyntaxError: Unexpected token ILLEGAL \n
$.ajax.success
</code>```

and when I click on it it directs me to the var obj = JSON.parse(data); line.

```<code>function getdata(){
    $.ajax({
        type:"GET",
        url: "https://gdata.youtube.com/feeds/api/users/TheSyndicateProject/playlists?v=2&alt=jsonc",
        data: "",
        success: function(data) {
            var obj = JSON.parse(data);
            displayPlaylists(obj);
        }

    });
}
</code>```

EDIT:
Ive found a solution that works in chrome but still not in IE

```<code>function getdata(){
        $.ajax({
                type:"GET",
                url: "https://gdata.youtube.com/feeds/api/users/TheSyndicateProject/playlists?v=2&alt=jsonc",
                dataType:"json",
                success: function(data) {
                    displayPlaylists(data);
                }

            });
    }
</code>```

the addition of dataType:"json" means that the function expects json data to be returned and therefore parses it on arrival (it is equivalent to using jQuery.parseJSON), however as i said this solution still doesn't work in IE

答:
set dataType to json and browser will automatically parse json for you, see if it works for you</p>

```<code>  function getdata(){
            $.ajax({
                    type:"GET",
                    dataType:'json',
                    contentType:'application/json',
                    url: "https://gdata.youtube.com/feeds/api/users/TheSyndicateProject/playlists?v=2&alt=jsonc",
                    data: "",
                    success: function(data) {
                        displayPlaylists(data);
                    }

                });
        }
</code>```

Body:
I'm having a problem within the jQuery ajax function. The following code works fine in Mozilla but doesn't work in IE or Chrome, when I try to identify the problem using Developer Tools in chrome I get the error:

Uncaught SyntaxError: Unexpected token ILLEGAL \n
$.ajax.success

and when I click on it it directs me to the var obj = JSON.parse(data); line.

function getdata(){
    $.ajax({
        type:"GET",
        url: "https://gdata.youtube.com/feeds/api/users/TheSyndicateProject/playlists?v=2&alt=jsonc",
        data: "",
        success: function(data) {
            var obj = JSON.parse(data);
            displayPlaylists(obj);
        }

    });
}

EDIT:
Ive found a solution that works in chrome but still not in IE

function getdata(){
        $.ajax({
                type:"GET",
                url: "https://gdata.youtube.com/feeds/api/users/TheSyndicateProject/playlists?v=2&alt=jsonc",
                dataType:"json",
                success: function(data) {
                    displayPlaylists(data);
                }

            });
    }

the addition of dataType:"json" means that the function expects json data to be returned and therefore parses it on arrival (it is equivalent to using jQuery.parseJSON), however as i said this solution still doesn't work in IE

Body:
set dataType to json and browser will automatically parse json for you, see if it works for you

  function getdata(){
            $.ajax({
                    type:"GET",
                    dataType:'json',
                    contentType:'application/json',
                    url: "https://gdata.youtube.com/feeds/api/users/TheSyndicateProject/playlists?v=2&alt=jsonc",
                    data: "",
                    success: function(data) {
                        displayPlaylists(data);
                    }

                });
        }


问:
Why does this for loop in C program print Hi 11 times?
```<code>#include <stdio.h>
int main()
{
int i = 1024;
for (; i; i >>= 1)
printf("Hi");
return 0;
}
</code>```

Why does the for loop print Hi 11 times? I don't understand.

答:
The >>= operator shifts the bits of the binary number to the right by the value on its right side, and assigns the result back to the variable. Here i is shifted to the right by 1. The least significant (rightmost) bit is discarded.

The loop condition in the middle of the for is just i, which is equivalent to i != 0 due to non-zero values being considered "truthy" and zero "falsey" in C.

1024 is 0b10000000000 in binary, i.e., a 1 followed by 10 zeroes. It will take 11 shifts to the right until the 1 "falls off" and leaves only zeroes, which causes the loop condition to no longer be true.

(As noted in other answers, shifting to the right by one bit is equivalent to integer division by two since the value of each binary digit further to the left is indeed one power of two greater than the previous (ones, twos, fours, eights, etc.), just like in decimal the values are powers of ten (ones, tens, hundreds, etc.). However, this is not really relevant to the question, since we can remain in the world of bits, as described above. Likewise even though integer division discards the fractional part, that is not why 1 >> 1 is zero…)

Body:
#include <stdio.h>
int main()
{
int i = 1024;
for (; i; i >>= 1)
printf("Hi");
return 0;
}

Why does the for loop print Hi 11 times? I don't understand.


答:
When working with dates, I would recommend you work with lubridate package. For example, working with nycflight sample dataset you can group with the function month() or whatever aggregation you want like this:

```<code>require(lubridate)
require(dplyr)
library(nycflights13)

data = flights

data %>%
  mutate(month_agg = month(time_hour)) %>%
  group_by(month_agg) %>%
  summarize(mean_air = mean(air_time,na.rm = T))
</code>```

Seems that there might be some problem when grouping by your column because of the format. Insuring it with lubricate can be a good approach I think.

Title: How can I summarise Meteorological data grouped by day (e.g. daily mean temperature)?

Body:
I'm working with a simple data frame. I want to summarise temperature data to find daily means.
But I'm having trouble grouping data by days (or date).
Here is my dataframe:

head(met_df)
    longdate     time     temp       ru
1 2022-01-17 19:35:16 26.45090 51.07734
2 2022-01-17 19:40:16 26.32881 52.05396
3 2022-01-17 19:45:16 26.10930 53.44564
4 2022-01-17 19:50:16 26.01184 53.39681
5 2022-01-17 19:55:16 25.79276 54.37344
6 2022-01-17 20:00:16 25.64688 54.81292

I tried

met_df %>%
  group_by(longdate) %>%
  summarise(mean = mean(temp))

found the overall mean temperature.

and also tried

summarise(met_df,
          group_by(longdate),
          meantemp = mean(temp))

to

Error in UseMethod("group_by_") :
  no applicable method for 'group_by_' applied to an object of class "character"

What am I doing wrong?

df is

    > dput(met_df[50:60,])
structure(list(longdate = c("2022-01-17", "2022-01-17", "2022-01-17",
"2022-01-17", "2022-01-18", "2022-01-18", "2022-01-18", "2022-01-18",
"2022-01-18", "2022-01-18", "2022-01-18"), time = c("23:40:16",
"23:45:16", "23:50:16", "23:55:16", "00:00:16", "00:05:16", "00:10:16",
"00:15:16", "00:20:16", "00:25:16", "00:30:16"), temp = c(21.6044187155778,
21.7954899898467, 21.7477126301733, 21.5805418389905, 21.4850494528608,
21.2464202287555, 21.0556153153795, 20.9364037750932, 20.8410563512717,
20.8887276946045, 20.8410563512717), ru = c(72.0258804858695,
71.0248428248795, 70.878349508637, 71.7573094060917, 72.1479582494049,
73.3443203320515, 74.4674357565769, 76.2009399987792, 75.7858756027589,
75.5661356283953, 76.3718488677287)), row.names = 50:60, class = "data.frame")

Thanks a lot

Body:
When working with dates, I would recommend you work with lubridate package. For example, working with nycflight sample dataset you can group with the function month() or whatever aggregation you want like this:

require(lubridate)
require(dplyr)
library(nycflights13)

data = flights

data %>%
  mutate(month_agg = month(time_hour)) %>%
  group_by(month_agg) %>%
  summarize(mean_air = mean(air_time,na.rm = T))

Seems that there might be some problem when grouping by your column because of the format. Insuring it with lubricate can be a good approach I think.


问:
Concatenate arrays with stack numpy
```<code>import numpy as np

t = np.arange(3)

for i in range(5):
  a = np.arange(3)
  np.stack((t, a))

print(t)
</code>```

output = [0 1 2]

Please some help to contatenate arrays in a loop for, ty!

答:
import numpy as np

t = np.arange(3)

for i in range(5):
  a = np.arange(3)
  t = np.concatenate((t, a))

print(t)
```
<p>Output:</p>
```[0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2]
```

Title: Concatenate arrays with stack numpy

Body:
import numpy as np

t = np.arange(3)

for i in range(5):
  a = np.arange(3)
  np.stack((t, a))

print(t)

output = [0 1 2]

Please some help to contatenate arrays in a loop for, ty!

Body:
import numpy as np

t = np.arange(3)

for i in range(5):
  a = np.arange(3)
  t = np.concatenate((t, a))

print(t)

Output:

[0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2]


问:
Time complexity of python two-sum solution
I have a question about the a widely accepted solution to the classic leetcode two-sum question, which reads as follows:

Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.

The solution I'm referring to iterates over nums and stores a mapping of values in nums to their indices. With each iteration over nums, we check if there is a complementary key to the current element in nums which would give us target, and if so we lookup and return its value:

```<code>    def twoSum(self, nums: List[int], target: int) -> List[int]:
        lookup = {}
        for i in range(0, len(nums)):
            if target - nums[i] in lookup:
                return [i, lookup[target - nums[i]]]
            lookup[nums[i]] = i
</code>```

Everyone seems to think this is an O(n) solution. However, I understand it to be O(n^2). For each iteration i, we're also iterating over potentially n-1 keys in the lookup table when we do nums[i] in lookup. Am I missing something?

答:
As lookup is a dictionary, it doesn't linearly search through its keys when looking up a value. It uses a mathematical function (called a hash) to calculate the value's location using the input key. This is an O(1) operation, meaning that checking if nums[i] in lookup is also an O(1) operation.

If lookup were a list, then you'd be right in saying the algorithm was O(n²)

You can google "Python how do dictionaries work" or something similar to find out more. I found this as the first result :)

Body:
I have a question about the a widely accepted solution to the classic leetcode two-sum question, which reads as follows:

Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.

The solution I'm referring to iterates over nums and stores a mapping of values in nums to their indices. With each iteration over nums, we check if there is a complementary key to the current element in nums which would give us target, and if so we lookup and return its value:

    def twoSum(self, nums: List[int], target: int) -> List[int]:
        lookup = {}
        for i in range(0, len(nums)):
            if target - nums[i] in lookup:
                return [i, lookup[target - nums[i]]]
            lookup[nums[i]] = i

Everyone seems to think this is an O(n) solution. However, I understand it to be O(n^2). For each iteration i, we're also iterating over potentially n-1 keys in the lookup table when we do nums[i] in lookup. Am I missing something?


问:
cmd package install-create -r -t --user current --full --dont-kill -S 9161306' returns error 'Unknown failure: cmd: Can't find service: package
how to fix
('cmd package install-create -r -t --user current --full --dont-kill -S 9161306' returns error 'Unknown failure: cmd: Can't find service: package')
and
(Error while waiting for device: Timed out after 300seconds waiting for emulator to come online.)
error when i launch the emulator.</p>

答:
The problem is most likely with your Android Emulator.

If so, the solution is to do a Cold Reboot of the Emulator:

(Open Android Virtual Device Manager from Tools > AVD Manager)

(Right Click on the Virtual Device that is generating the error and choose Cold Boot Now)