Страницы

Поиск по вопросам

вторник, 26 февраля 2019 г.

Callback загрузки карты yandex map

Имеется пустая страница с картой для печати. С помощью window.print() вызывается на печать. Проблема заключается в том, что карта не успевает отрисоваться. Никак не могу нагуглить и нарыть в их замечательной документации какой-то вариант события или callback'a именно на готовность карты.
Есть предложения, коллеги?
ymaps.ready(function() { ymaps.ready(init); var map, object;
function init() { var center = settings.map.center, zoom = parseInt(settings.map.zoom), coords_point = settings.map.coords_point;
center = center.split(',').map(parseFloat); coords_point = coords_point.split(',').map(parseFloat);
map = new ymaps.Map('yamap', { center: center, zoom: zoom, controls: [], });
object = new ymaps.GeoObject({ geometry: { type: "Point", coordinates: coords_point }, }, { preset: 'custom#point_green', });
map.geoObjects.add(object); }
ymaps.option.presetStorage.add('custom#point_green', { iconLayout: 'default#image', iconImageHref: settings.themePath + '/img/yamap_point_g.png', iconImageSize: [48, 41], iconImageOffset: [-15, -41], hideIconOnBalloonOpen: false, }); });
Обновление
Пример вызова window.print()
Пример на JsFiddle
ymaps.ready(function() { ymaps.ready(init); var map, object; function init() { var center = "56.83676954481658,60.61677207117298", zoom = 15, coords_point = "56.836098132297586,60.61771118192043"; center = center.split(',').map(parseFloat); coords_point = coords_point.split(',').map(parseFloat); map = new ymaps.Map('yamap', { center: center, zoom: zoom, controls: [], }); object = new ymaps.GeoObject({ geometry: { type: "Point", coordinates: coords_point }, }); map.geoObjects.add(object); } }); window.print(); #yamap { width: 300px; height: 200px; }



Ответ

Поместите хотя бы window.print() внутрь ymaps.ready() и вместо ymaps.ready(init) вызывайте просто init()
Дополнено
Событий, однозначно показывающих полное окончание всех процедур составления карты пока нет. Однако, как показывает практика, загрузка карты заканчивается загрузкой всех тайлов. И в документации есть описание как можно добавлять новые слои с тайлами. Это делается при помощи классов layer.tileContainer.CanvasContainer и layer.tileContainer.DomContainer. У этих-то классов есть событие ready, которое вызывается когда все тайлы слоя загружены. И они даже используются при отображении карт, но до их экземпляра не так просто добраться.
Если вы ничего не делаете со слоями, то на карте есть один единственный слой (если слоев все-таки несколько, придется обрабатывать все слои в циклах), к которому можно достучаться вот так
var layer = map.layers.get(0).get(0); /* Сначала мы получаем первый экземпляр коллекции слоев, потом первый слой коллекции */
Так мы получаем экземпляр Layer, но в его описании нету ничего про tileContainer, однако это поле там есть, только оно как бы приватное и при минимизации становится неудобоваримым (в debug версии это поле _tileContainer). Чтобы его найти можно воспользоваться вот такой функцией:
function getTileContainer(layer) { for (var k in layer) { if (layer.hasOwnProperty(k)) { if ( layer[k] instanceof ymaps.layer.tileContainer.CanvasContainer || layer[k] instanceof ymaps.layer.tileContainer.DomContainer ) { return layer[k]; } } } return null; }
Теперь можно сделать так:
var tc = getTileContainer(layer); tc.events.once("ready", function() { // Вызываем, например, печать документа window.print(); });
Одно плохо. Мы не узнаем о загрузке всех тайлов если выяснится, что мы не успели начать слушать событие до окончания загрузки тайлов. Неплохо было бы знать вообще чего-то ждем или нет. Для этого перед "подслушиванием" события нужно узнать есть-ли "неготовые" тайлы. Это можно проверить если перебрать все тайлы в контейнере и вызвать методы isReady() для layer.tile.CanvasTile или layer.tile.DomTile, после этого, если неготовые тайлы есть подключать событие. Будет удобно сделать такую функцию, которая будет возвращать промис.
function waitForTilesLoad(layer) { return new ymaps.vow.Promise(function (resolve, reject) { var tc = getTileContainer(layer), readyAll = true; tc.tiles.each(function (tile, number) { if (!tile.isReady()) { readyAll = false; } }); if (readyAll) { resolve(); } else { tc.events.once("ready", function() { resolve(); }); } }); }
В вашем случае этой функцией можно воспользоваться так:
waitForTilesLoad(layer).then(function() { window.print(); });

Как узнать имя приложения

Для начала определимся с терминами в данном контексте, на примере браузера Google Chrome.
Имя процесса: chrome.exe
Имя приложения: Google Chrome (32 bit)

Мне нужно узнать именно имя приложения, так как оно почти всегда отличается.


Ответ

Возьмите за основу этот пример:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Management; using System.Diagnostics; using System.Management.Instrumentation;
namespace getAllProcessID { class Program { static void Main(string[] args) { var myID = Process.GetCurrentProcess(); var query = string.Format("SELECT ParentProcessId FROM Win32_Process");// WHERE ProcessId = {0}", myID); var search = new ManagementObjectSearcher("root\\CIMV2", query); var results = search.Get().GetEnumerator();
if (!results.MoveNext()) throw new Exception("Huh?");
var queryObj = results.Current; uint parentId = (uint)queryObj["ParentProcessId"];
foreach (Process p in Process.GetProcesses()) { if (p.MainWindowTitle.Length > 0) { Console.WriteLine(p.MainWindowTitle.ToString()); Console.WriteLine(p.ProcessName.ToString()); Console.WriteLine(p.MainWindowHandle.ToString()); Console.WriteLine(p.PrivateMemorySize64.ToString()); } } Console.ReadLine(); } } }

Linq Group VS Join+Into

Подскажите пожалуйста в чем преимущество использования в Linq запросе комбинации Join+Into перед group. Что один, что второй используются для группировки сходных по определенных критериев объектов в массив. Однако зачем использовать Join+Into если, все сортировочные критерии есть и так в нужном массиве. Например есть две последовательности:
List type = new List() { 1,2,3,4 }; List classes = new List() { new Tov(4, "Велосипед"), new Tov(1, "Автомобиль"), new Tov(2, "Катер"), new Tov(4, "Мопед"), new Tov(3, "Самолет"), new Tov(2, "Лодка"), new Tov(1, "Самосвал"), new Tov(4, "Самокат"), new Tov(2, "Корабль"), };
В чем преимущество, например этого запроса
var v = from t in classes group t by t.id;
От этого :
var v = from t in type join cl in classes on t equals cl.id into Mass select new { Type = t, Mass };
Ведь в результате мы все равно как в первом так и во втором случае получим набор из массивов где объекты определены по одному признаку. И есть ли такой пример, где невозможно воспользоваться одним способом, зато можно другим ? Спасибо.


Ответ

Group by - это аггрегация данных, т.е. результат будет содержать столько же или меньше (в случае повтороения значений) строк. Join - это содениение данных, т.е. результат будет содержать столько же и никак не меньше строк.
Если в список type будут повторяющиеся значения, то результат второго запроса поменяется. Для такого списка:
var type = new List() { 1, 2, 3, 4, 3 , 2, 1 };
Второй запрос вернет семь строк, а не 4 как первый.
DotNetFiddle пример

В другом случае, когда не для каждого значения id из списка type будут существовать соответствующие значения в списке classes - во втором запросе, для каждого такого значения id из списка type вернется пустой список значений из classes.
DotNetFiddle пример

Проблема в построении логического ИИ

Я делаю для презентации лабораторной работы программу где реализован логический ИИ. Сдел её на JS.
Часть исполнения таково: есть "вход" где появляется группа пикселей "муравьев", бесцельно бродящих близ "входа" и как только на поле выложить "еду" (пиксели другого цвета), то "муравьи" идут к еде и "тащат" её на "выход".
В целом всё готово, но мне не понравилось, что "муравей" выбирает свою целевую еду слишком просто - берется следующий элемент массива, где хранятся объекты "еда". Я решил сделать так, что бы "муравей" выбирал ближайший от своей текущей координаты объект "еда".
Однако не смотря на, казалось бы, правильно (по моему мнению) написанный код, все равно ничего не выходит.
Вот функция поиска "цели" "муравья":
function checkEat(id) //Проверка на наличие еды { var bestTarget = ""; var t = Infinity,l = Infinity; //будущие координаты "цели" if (!antArmy[id].antOnTheHunt) //если муравей еще не охотится if (eatStock.length > storageCount) { //если вся "еда" еще не утащена на "выход" for (var eatAll = 0; eatAll <= eatStock.length; eatAll++) { //идем по массиву объектов "еда" if (eatStock[eatAll] != "returned") //если "еда" уже не утащена if (!eatStock[eatAll].grabbed && !eatStock[eatAll].onTarget) //если "еда" не схвачена другим "муравьем" { //и на неё не претендует другой "муравей"... var AntPT = getElemCoordinates(antArmy[id].name, "top"); //координаты текущего муравья var AntPL = getElemCoordinates(antArmy[id].name, "left"); var eatPT = getElemCoordinates(eatStock[eatAll].name, "top"); //координаты текущей еды var eatPL = getElemCoordinates(eatStock[eatAll].name, "left"); if ((Math.abs(AntPT - eatPT) + Math.abs(AntPL - eatPL)) < (t + l)) { //сравниваем сумму координат t = eatPT; //если следующая сумма координат будет меньше ( а то есть ближе к "муравью") l = eatPL; // то будут вписаны новые координаты ближайшего объекта bestTarget = eatStock[eatAll].name; //пока не выберется ближайшая "еда" } } } } alert(bestTarget); //проверка на работу (проверка не успешна) antArmy[id].antOnTheHunt = true; //"муравей" выходит на охоту antArmy[id].targetEat = bestTarget; //выбирает ближайшую "еду" eatStock[bestTarget].onTarget = true; //"еда" "помечена" storageCount++; }
Посоветуете что-нибудь, пожалуйста? А то не смотря на дни, просиженные над этим куском кода, ошибка мне не понятна. А узнать и реализовать очень интересно (
Вот полный код всей программы. Здесь нет предыдущей вставки и она рабочая. Правда желательно запускать не через какой-то веб редактор, а напрямую с файла, дабы не было каких-то ошибок.
var enter = false; var exit = false; var eat = false; var enter_place = false; var exit_place = false; var eat_place = false; var antArmy = []; var antArmyFull = false; var eatStock = []; var storageCount = 0; //Подсчет кол-во отнесенной на выход еды function ruler(command) { //подтверждает выбор инструмента. Когда пользователь кликнет на поле, ruler определит, //что установить на поле if (command) { switch (command) { case "enter": enter_place = true; exit_place = false; eat_place = false; if (enter) document.getElementById('choose').innerHTML = '"Enter" is already placed'; else document.getElementById('choose').innerHTML = '"Enter" is choosed'; break; case "exit": enter_place = false; exit_place = true; eat_place = false; if (exit) document.getElementById('choose').innerHTML = '"Exit" is already placed'; else document.getElementById('choose').innerHTML = '"Exit" is choosed'; break; case "eat": enter_place = false; exit_place = false; eat_place = true; if (eat) document.getElementById('choose').innerHTML = '"Eat" is already placed'; else document.getElementById('choose').innerHTML = '"Eat" is choosed'; break; default: alert("something wrong with function 'ruler'."); } } } function releaseAnt() { //конвеер муравьев if (enter === true) { while (antArmyFull === false) { antArmy[antArmy.length] = new MakeAnt("ant" + antArmy.length); if (antArmy.length >= 50) antArmyFull = true; } document.getElementById('numOfAnts').innerHTML = 'Ant army size: ' + antArmy.length + '.'; moveAnt(); } } function releaseEat(posX, posY){ //конвеер еды var x = posX; var y = posY; var placing = eatStock.length + 60; while (eatStock.length <= placing) { if (x >= posX+40) { x = posX; y++; } eatStock[eatStock.length] = new PlaceEat(eatStock.length, x, y); x++; } eat = true; } ///////////////////////ANT///////////////////////// function MakeAnt(name) { //конструктор муравья this.name = name; this.antOnTheHunt = false; this.targetEat = ""; this.antGrabEat = false; var positionOfHome = document.getElementById("enterance"); var ant_div = document.body.appendChild(document.createElement('div')); //создаем div с атррибутами ant_div.setAttribute("id", name); /* В качестве начальных координат используются координаты "Входа" */ ant_div.style.cssText="position:absolute;\ top:" + parseInt(positionOfHome.style.top, 10) + ";\left:" + parseInt(positionOfHome.style.left, 10) + ";"; var annt_canvas = ant_div.appendChild(document.createElement('canvas')); //создаем холст с атррибутами annt_canvas.setAttribute("id", "a" + name); var ant_canvas = document.getElementById("a" + name);//находим холст var ant_context = ant_canvas.getContext("2d");//устанавливаем 2d рисование ant_context.fillStyle = "#000000";//цвет заливки ant_context.fillRect(0, 0, 1, 1);//создаем квадрат и заливаем } ///////////////////////ANT MOVE//////////////////////// function moveAnt() { //управляющая выбором движения муравья функция for (var i = 0; i < antArmy.length; i++) { if (eat) checkEat(i); if (!antArmy[i].antOnTheHunt && !antArmy[i].antGrabEat) { checkMove(antArmy[i].name); walkLikeADrunk(i); //хаотичное передвижение } if (exit) { // if (!antArmy[i].antOnTheHunt) moveToTheExit(i); //Двигаться к выходу, если он существует if (antArmy[i].antOnTheHunt && antArmy[i].antGrabEat) bringEatBack(i); //Двигаться с едой к выходу } if (antArmy[i].antOnTheHunt && !antArmy[i].antGrabEat) huntForEat(i); //охотится за едой } setTimeout("moveAnt()", 100) } function move(who,where,line) { //line === "left" or "top" if (line === "left") document.getElementById(who).style.left=parseInt(document.getElementById(who).style.left)+where; if (line === "top") document.getElementById(who).style.top=parseInt(document.getElementById(who).style.top)+where; } function walkLikeADrunk(id) { var rand = Math.round(Math.random() * (4 - 1) + 1); switch (rand) { case 2: move(antArmy[id].name, 1, "left"); break; case 3: move(antArmy[id].name, -1, "left"); break; case 1: move(antArmy[id].name, 1, "top"); break; case 4: move(antArmy[id].name, -1, "top"); break; default: alert("move ant error"); } } function huntForEat(id) { if (antArmy[id].targetEat !== "") { var eatPosTop = getElemCoordinates(antArmy[id].targetEat,"top"); var eatPosLeft = getElemCoordinates(antArmy[id].targetEat,"left"); var AntPosTop = getElemCoordinates(antArmy[id].name,"top"); var AntPosLeft = getElemCoordinates(antArmy[id].name,"left"); if (eatPosTop < AntPosTop) move(antArmy[id].name, -1, "top"); else move(antArmy[id].name, 1, "top"); if (eatPosLeft < AntPosLeft) move(antArmy[id].name, -1, "left"); else move(antArmy[id].name, 1, "left"); checkEatBorder(id); } } function bringEatBack(id) { var AntCurrPosTop = getElemCoordinates(antArmy[id].name,"top"); var AntCurrPosLeft = getElemCoordinates(antArmy[id].name,"left"); var eatPosTop = getElemCoordinates(antArmy[id].targetEat,"top"); var eatPosLeft = getElemCoordinates(antArmy[id].targetEat,"left"); moveToTheExit(id); var AntPastPosTop = getElemCoordinates(antArmy[id].name,"top"); var AntPastPosLeft = getElemCoordinates(antArmy[id].name,"left"); if (AntPastPosTop <= AntCurrPosTop) eatPosTop = AntPastPosTop-1; else eatPosTop = AntPastPosTop+1; if (AntPastPosLeft <= AntCurrPosLeft) eatPosLeft = AntPastPosLeft-1; else eatPosLeft = AntPastPosLeft+1; document.getElementById(antArmy[id].targetEat).style.left=eatPosLeft; document.getElementById(antArmy[id].targetEat).style.top=eatPosTop; } function checkMove(name) //Проверка движения муравья, относительно положения "Входа" { //Если муравей не на "охоте", то он не уходит за установленные границы var AntPosCheckTop = getElemCoordinates(name,"top"); var AntPosCheckLeft = getElemCoordinates(name,"left"); var borderLineTop = getElemCoordinates("enterance","top"); var borderLineLeft = getElemCoordinates("enterance","left"); if ((borderLineTop < AntPosCheckTop) && (borderLineLeft < AntPosCheckLeft)) { if (((borderLineLeft + 50) < AntPosCheckLeft) || ((borderLineTop + 50) < AntPosCheckTop)) { if (borderLineTop < AntPosCheckTop) move(name, -1, "top"); if (borderLineLeft < AntPosCheckLeft) move(name, -1, "left"); } } if ((borderLineTop > AntPosCheckTop) && (borderLineLeft < AntPosCheckLeft)) { if (((borderLineLeft + 50) < AntPosCheckLeft) || ((borderLineTop - 50) > AntPosCheckTop)) { if (borderLineTop > AntPosCheckTop) move(name, 1, "top"); if (borderLineLeft < AntPosCheckLeft) move(name, -1, "left"); } } if ((borderLineTop > AntPosCheckTop) && (borderLineLeft > AntPosCheckLeft)) { if (((borderLineLeft - 50) > AntPosCheckLeft) || ((borderLineTop - 50) > AntPosCheckTop)) { if (borderLineTop > AntPosCheckTop) move(name, 1, "top"); if (borderLineLeft > AntPosCheckLeft) move(name, 1, "left"); } } if ((borderLineTop < AntPosCheckTop) && (borderLineLeft > AntPosCheckLeft)) { if (((borderLineLeft - 50) > AntPosCheckLeft) || ((borderLineTop + 50) < AntPosCheckTop)) { if (borderLineTop < AntPosCheckTop) move(name, -1, "top"); if (borderLineLeft > AntPosCheckLeft) move(name, 1, "left"); } } } function checkExitBorder(id) { var AntPosCheckTop = getElemCoordinates(antArmy[id].name, "top"); //позиция муравья var AntPosCheckLeft = getElemCoordinates(antArmy[id].name, "left"); var exitLineTop = getElemCoordinates("exit", "top"); //позиция выхода var exitLineLeft = getElemCoordinates("exit", "left"); var startLineTop = getElemCoordinates("enterance", "top"); //позиция входа var startLineLeft = getElemCoordinates("enterance", "left"); //это нам нужно что бы возвратить муравья if ((exitLineTop <= AntPosCheckTop) && (exitLineLeft <= AntPosCheckLeft)) { if (((exitLineLeft + 5) > AntPosCheckLeft) && ((exitLineTop + 5) > AntPosCheckTop)) { if (antArmy[id].antGrabEat) { eatStock[antArmy[id].targetEat] = "returned"; antArmy[id].antOnTheHunt = false; antArmy[id].antGrabEat = false; } document.getElementById(antArmy[id].name).style.top = "" + startLineTop + "px"; document.getElementById(antArmy[id].name).style.left = "" + startLineLeft + "px"; } } if ((exitLineTop > AntPosCheckTop) && (exitLineLeft < AntPosCheckLeft)) { if (((exitLineLeft + 5) > AntPosCheckLeft) && ((exitLineTop - 5) < AntPosCheckTop)) { if (antArmy[id].antGrabEat) { eatStock[antArmy[id].targetEat] = "returned"; antArmy[id].antOnTheHunt = false; antArmy[id].antGrabEat = false; } document.getElementById(antArmy[id].name).style.top = "" + startLineTop + "px"; document.getElementById(antArmy[id].name).style.left = "" + startLineLeft + "px"; } } if ((exitLineTop >= AntPosCheckTop) && (exitLineLeft >= AntPosCheckLeft)) { if (((exitLineLeft - 5) < AntPosCheckLeft) && ((exitLineTop - 5) < AntPosCheckTop)) { if (antArmy[id].antGrabEat) { eatStock[antArmy[id].targetEat] = "returned"; antArmy[id].antOnTheHunt = false; antArmy[id].antGrabEat = false; } document.getElementById(antArmy[id].name).style.top = "" + startLineTop + "px"; document.getElementById(antArmy[id].name).style.left = "" + startLineLeft + "px"; } } if ((exitLineTop < AntPosCheckTop) && (exitLineLeft > AntPosCheckLeft)) { if (((exitLineLeft - 5) < AntPosCheckLeft) && ((exitLineTop + 5) > AntPosCheckTop)) { if (antArmy[id].antGrabEat) { eatStock[antArmy[id].targetEat] = "returned"; antArmy[id].antOnTheHunt = false; antArmy[id].antGrabEat = false; } document.getElementById(antArmy[id].name).style.top = "" + startLineTop + "px"; document.getElementById(antArmy[id].name).style.left = "" + startLineLeft + "px"; } } } function checkEatBorder(id) { var AntPosCheckTop = getElemCoordinates(antArmy[id].name,"top"); //позиция муравья var AntPosCheckLeft = getElemCoordinates(antArmy[id].name,"left"); var eatPosTop = getElemCoordinates(antArmy[id].targetEat,"top"); var eatPosLeft = getElemCoordinates(antArmy[id].targetEat,"left"); if ((eatPosTop <= AntPosCheckTop) && (eatPosLeft <= AntPosCheckLeft)) { if (((eatPosLeft + 2) > AntPosCheckLeft) && ((eatPosTop + 2) > AntPosCheckTop)) { antArmy[id].antGrabEat = true; eatStock[antArmy[id].targetEat].grabbed = true; } } if ((eatPosTop > AntPosCheckTop) && (eatPosLeft < AntPosCheckLeft)) { if (((eatPosLeft + 2) > AntPosCheckLeft) && ((eatPosTop - 2) < AntPosCheckTop)) { antArmy[id].antGrabEat = true; eatStock[antArmy[id].targetEat].grabbed = true; } } if ((eatPosTop >= AntPosCheckTop) && (eatPosLeft >= AntPosCheckLeft)) { if (((eatPosLeft - 2) < AntPosCheckLeft) && ((eatPosTop - 2) < AntPosCheckTop)) { antArmy[id].antGrabEat = true; eatStock[antArmy[id].targetEat].grabbed = true; } } if ((eatPosTop < AntPosCheckTop) && (eatPosLeft > AntPosCheckLeft)) { if (((eatPosLeft - 2) < AntPosCheckLeft) && ((eatPosTop + 2) > AntPosCheckTop)) { antArmy[id].antGrabEat = true; eatStock[antArmy[id].targetEat].grabbed = true; } } } /*function checkEat(id) //Проверка на наличие еды { var bestTarget = ""; var t = Infinity,l = Infinity; if (!antArmy[id].antOnTheHunt) if (eatStock.length > storageCount) { for (var eatAll = 0; eatAll <= eatStock.length; eatAll++) { if (eatStock[eatAll] != "returned") if (!eatStock[eatAll].grabbed && !eatStock[eatAll].onTarget) { var AntPT = getElemCoordinates(antArmy[id].name, "top"); var AntPL = getElemCoordinates(antArmy[id].name, "left"); var eatPT = getElemCoordinates(eatStock[eatAll].name, "top"); var eatPL = getElemCoordinates(eatStock[eatAll].name, "left"); if ((Math.abs(AntPT - eatPT) + Math.abs(AntPL - eatPL)) < (t + l)) { t = eatPT; l = eatPL; bestTarget = eatStock[eatAll].name; } } } }*/ function checkEat(id) //Проверка на наличие еды { if (!antArmy[id].antOnTheHunt) if (eatStock.length > storageCount) { for (var eatAll = 0; eatAll <= eatStock.length; eatAll++) { if (eatStock[eatAll] != "returned") if (!eatStock[eatAll].grabbed && !eatStock[eatAll].onTarget) { antArmy[id].antOnTheHunt = true; antArmy[id].targetEat = eatAll; eatStock[eatAll].onTarget = true; storageCount++; break; } } } } function moveToTheExit(id) { var exitPosTop = getElemCoordinates("exit","top"); var exitPosLeft = getElemCoordinates("exit","left"); var AntPosTop = getElemCoordinates(antArmy[id].name,"top"); var AntPosLeft = getElemCoordinates(antArmy[id].name,"left"); checkExitBorder(id); if (exitPosTop < AntPosTop) move(antArmy[id].name, -1, "top"); else move(antArmy[id].name, 1, "top"); if (exitPosLeft < AntPosLeft) move(antArmy[id].name, -1, "left"); else move(antArmy[id].name, 1, "left"); } function PlaceEat(eatid, posX, posY) { //конструктор еды this.name = eatid; this.onTarget = false; this.grabbed = false; var eat_div = document.body.appendChild(document.createElement('div')); //создаем div с атррибутами eat_div.setAttribute("id", eatid); eat_div.style.cssText = "position:absolute;\ top:" + posY + ";\left:" + posX + ";"; var eaat_canvas = eat_div.appendChild(document.createElement('canvas')); //создаем холст с атррибутами eaat_canvas.setAttribute("id", "eat" + eatid); var eat_canvas = document.getElementById("eat" + eatid);//находим холст var eat_context = eat_canvas.getContext("2d");//устанавливаем 2d рисование eat_context.fillStyle = "#FFA500";//цвет заливки eat_context.fillRect(0, 0, 1, 1);//создаем квадрат и заливаем } //Функция реагирования на "клик" пользователя. //Если инструмент выбран... document.addEventListener('click', function (e) { if ((document.elementFromPoint(e.clientX, e.clientY).tagName) != "BUTTON") { ////////////////////ENTERANCE///////////////////// if (enter_place === true) { if (enter === false) { var enter_div = document.body.appendChild(document.createElement('div')); //создаем div с атррибутами enter_div.setAttribute("id", "enterance"); enter_div.style.cssText="position:absolute;\ top:" + e.pageY + ";\left:" + e.pageX + ";"; var enteer_canvas = enter_div.appendChild(document.createElement('canvas')); //создаем холст с атррибутами enteer_canvas.setAttribute("id", "e"); var enter_canvas = document.getElementById("e");//находим холст var enter_context = enter_canvas.getContext("2d");//устанавливаем 2d рисование enter_context.fillStyle = "#000080";//цвет заливки enter_context.fillRect(0, 0, 10, 10);//создаем квадрат и заливаем enter = true; releaseAnt(); } } //////////////////EXIT//////////////////////// if (exit_place === true) { if (exit === false) { var exit_div = document.body.appendChild(document.createElement('div')); //создаем div с атррибутами exit_div.setAttribute("id", "exit"); exit_div.style.cssText="position:absolute;\ top:" + e.pageY + ";\left:" + e.pageX + ";"; var exiit_canvas = exit_div.appendChild(document.createElement('canvas')); //создаем холст с атррибутами exiit_canvas.setAttribute("id", "ex"); var exit_canvas = document.getElementById("ex");//находим холст var exit_context = exit_canvas.getContext("2d");//устанавливаем 2d рисование exit_context.fillStyle = "#FF0000";//цвет заливки exit_context.fillRect(0, 0, 10, 10);//создаем квадрат и заливаем exit = true; } } ////////////////EAT//////////////////////// if (eat_place === true) { releaseEat(e.pageX, e.pageY); } } }, false); function getElemCoordinates(name,side) //side = top/left { if (side === "top") return parseInt(document.getElementById(name).style.top, 10); if (side === "left") return parseInt(document.getElementById(name).style.left, 10); } //Вызов elem.cloneNode(true) создаст «глубокую» копию элемента //parentElem.removeChild(elem)


Ответ

if ((Math.abs(AntPT - eatPT) + Math.abs(AntPL - eatPL)) < (t + l))
Вы берете расстояние между муравьем и едой и сравниваете с абсолютными координатами другой еды, что в корне не верно. Вам надо помнить САМО РАССТОЯНИЕ
var t=Infinity; ... if ((Math.abs(AntPT - eatPT) + Math.abs(AntPL - eatPL)) < t) { t=(Math.abs(AntPT - eatPT) + Math.abs(AntPL - eatPL); .... }

Не создается таблица sqlite при обновлении приложения

protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.predmet_zapis); dbHelper = new DBHelper(this);
ed1 = (EditText) findViewById(R.id.et_predmet); bt1 = (Button) findViewById(R.id.but1); bt1.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) { bd = dbHelper.getWritableDatabase(); ContentValues cv = new ContentValues(); String chisl1 = ed1.getText().toString(); cv.put("chisl", chisl1); long rowID = bd.insert("mypoints", null, cv); Log.d("LOG_TAG", "row inserted, ID = " + rowID); dbHelper.close(); } }); }
public class DBHelper extends SQLiteOpenHelper {
public DBHelper(Context context) { // конструктор суперкласса super(context, "myDB", null, 1); }
@Override public void onCreate(SQLiteDatabase db) { // создаем таблицу с полями Log.d("123","cоздана БД"); db.execSQL("create table mypoints (" + "id integer primary key autoincrement," + "chisl text"+");"); }
@Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
} }
Пытаюсь создать БД, но не создается. Пишет "no such table: mypoints".
Удалил приложение с телефона, заново установил - заработало, но после того как решил поменять название таблицы, перестало работать с той же ошибкой, почему так?


Ответ

onCreate вызывается когда нет БД. При обновлении приложения БД уже существует и onCreate не вызывается, следовательно новая таблица не создаётся.
Если вы решили изменить структуру БД, то нужно увеличить номер версии БД в вызове родительского конструктора:
super(context, "myDB", null, 2);
И в функцию onUpgrade добавить логику: что делать для приведения старой БД к новой структуре:
@Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { if(oldVersion < 2) { db.execSQL("alter table mytable rename to mypoints;"); } }

Замена стандартного WebBrowser C#

Как я понял, стандартный элемент WebBrowser базируется на IE 7.0. Некорректно отображается нужный мне сайт. Можно ли обновить его хотя бы до 11 версии? Или существуют ли сторонние библиотеки/фреймворки как альтернатива?


Ответ

WebBrowser базируется на текущем IE, но он принудительно запускается в режиме совместимости с IE7.
Решение - перед инициализацией контрола вписать в реестр по пути Software\Microsoft\Internet Explorer\Main\FeatureControl\myapp.exe ключ FEATURE_BROWSER_EMULATION со значением, соответствующим нужной версии браузера. Полный код для приведения WebBrowser в нормальный рабочий вид выглядит так:
private void SetBrowserFeatureControlKey(string feature, string appName, uint value) { using (var key = Registry.CurrentUser.CreateSubKey( String.Concat(@"Software\Microsoft\Internet Explorer\Main\FeatureControl\", feature), RegistryKeyPermissionCheck.ReadWriteSubTree)) { key.SetValue(appName, (UInt32)value, RegistryValueKind.DWord); } }
private void SetBrowserFeatureControl() { // http://msdn.microsoft.com/en-us/library/ee330720(v=vs.85).aspx
// FeatureControl settings are per-process var fileName = System.IO.Path.GetFileName(Process.GetCurrentProcess().MainModule.FileName);
// make the control is not running inside Visual Studio Designer if (String.Compare(fileName, "devenv.exe", true) == 0 || String.Compare(fileName, "XDesProc.exe", true) == 0) return;
SetBrowserFeatureControlKey("FEATURE_BROWSER_EMULATION", fileName, GetBrowserEmulationMode()); // Webpages containing standards-based !DOCTYPE directives are displayed in IE10 Standards mode. SetBrowserFeatureControlKey("FEATURE_AJAX_CONNECTIONEVENTS", fileName, 1); SetBrowserFeatureControlKey("FEATURE_ENABLE_CLIPCHILDREN_OPTIMIZATION", fileName, 1); SetBrowserFeatureControlKey("FEATURE_MANAGE_SCRIPT_CIRCULAR_REFS", fileName, 1); SetBrowserFeatureControlKey("FEATURE_DOMSTORAGE ", fileName, 1); SetBrowserFeatureControlKey("FEATURE_GPU_RENDERING ", fileName, 1); SetBrowserFeatureControlKey("FEATURE_IVIEWOBJECTDRAW_DMLT9_WITH_GDI ", fileName, 0); SetBrowserFeatureControlKey("FEATURE_DISABLE_LEGACY_COMPRESSION", fileName, 1); SetBrowserFeatureControlKey("FEATURE_LOCALMACHINE_LOCKDOWN", fileName, 0); SetBrowserFeatureControlKey("FEATURE_BLOCK_LMZ_OBJECT", fileName, 0); SetBrowserFeatureControlKey("FEATURE_BLOCK_LMZ_SCRIPT", fileName, 0); SetBrowserFeatureControlKey("FEATURE_DISABLE_NAVIGATION_SOUNDS", fileName, 1); SetBrowserFeatureControlKey("FEATURE_SCRIPTURL_MITIGATION", fileName, 1); SetBrowserFeatureControlKey("FEATURE_SPELLCHECKING", fileName, 0); SetBrowserFeatureControlKey("FEATURE_STATUS_BAR_THROTTLING", fileName, 1); SetBrowserFeatureControlKey("FEATURE_TABBED_BROWSING", fileName, 1); SetBrowserFeatureControlKey("FEATURE_VALIDATE_NAVIGATE_URL", fileName, 1); SetBrowserFeatureControlKey("FEATURE_WEBOC_DOCUMENT_ZOOM", fileName, 1); SetBrowserFeatureControlKey("FEATURE_WEBOC_POPUPMANAGEMENT", fileName, 0); SetBrowserFeatureControlKey("FEATURE_WEBOC_MOVESIZECHILD", fileName, 1); SetBrowserFeatureControlKey("FEATURE_ADDON_MANAGEMENT", fileName, 0); SetBrowserFeatureControlKey("FEATURE_WEBSOCKET", fileName, 1); SetBrowserFeatureControlKey("FEATURE_WINDOW_RESTRICTIONS ", fileName, 0); SetBrowserFeatureControlKey("FEATURE_XMLHTTP", fileName, 1); }
private UInt32 GetBrowserEmulationMode() { int browserVersion = 7; using (var ieKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Internet Explorer", RegistryKeyPermissionCheck.ReadSubTree, System.Security.AccessControl.RegistryRights.QueryValues)) { var version = ieKey.GetValue("svcVersion"); if (null == version) { version = ieKey.GetValue("Version"); if (null == version) throw new ApplicationException("Microsoft Internet Explorer is required!"); } int.TryParse(version.ToString().Split('.')[0], out browserVersion); }
UInt32 mode = 11000; // Internet Explorer 11. Webpages containing standards-based !DOCTYPE directives are displayed in IE11 Standards mode. Default value for Internet Explorer 11. switch (browserVersion) { case 7: mode = 7000; // Webpages containing standards-based !DOCTYPE directives are displayed in IE7 Standards mode. Default value for applications hosting the WebBrowser Control. break; case 8: mode = 8000; // Webpages containing standards-based !DOCTYPE directives are displayed in IE8 mode. Default value for Internet Explorer 8 break; case 9: mode = 9000; // Internet Explorer 9. Webpages containing standards-based !DOCTYPE directives are displayed in IE9 mode. Default value for Internet Explorer 9. break; case 10: mode = 10000; // Internet Explorer 10. Webpages containing standards-based !DOCTYPE directives are displayed in IE10 mode. Default value for Internet Explorer 10. break; default: // use IE11 mode by default break; }
return mode; }
public Form1() { // до создания контрола SetBrowserFeatureControl();
InitializeComponent();
webBrowser1.Url = new Uri("https://www.whatismybrowser.com/"); }
код взят с enSO: C# webbrowser Ajax call.

Поставить третью систему

Есть Windows 7 и Linix. Хочу дополнительно к ним поставить Windows 10.
Вопрос, надо ли что-то делать с grub'ом переду установкой Win10? Или можно по стандартной схеме просто поставить Win10, затем загрузиться с LiveUSB, откуда установить и настройть grub? Или же следует сначала откатиться от grub'а до виндового загрузчика, чтобы Win10 при установке смог его определить?
Повторю, что в итоге я хочу получить Win7 + Linux + Win10.


Ответ

После того, как вы установите Windows 10 (не повреждая файлы других ОС) нужно будет загрузиться с Linux и выполнить boot-repair в терминале. Не зависимо от того, увидит десятка семёрку или нет (хотя по идее должна увидеть), GRUB восстановит доступ ко всем трём ОС.

Связать Combobox с колонкой dataGrid wpf

Приветствую, народ! Мой вопрос заключается в следующем: Есть форма wpf
selectedObjectsDataGrid.ItemsSource = attributesManager.ObjectsInGrid;
Ее сорс - это лист объектов ObjectInGrid
public class ObjectInGrid { private ObjType? type; public Guid Object { get; set; } public ObjType? Type { get { return type; } set { type = value; } }
public ObjectInGrid(Guid obj) { Object = obj; } public enum ObjType { None = 0, Door = 1, Window = 2 } }
В комбобоксе есть три варианта (как в enum ObjType). Объекты поступают в датагрид так: пользователь выделяет один или несколько объектов в документе. по нажатию, грубо говоря, создается объект
public void AddObjectToGrid(Guid id) { ObjectInGrid o = new ObjectInGrid(id); ObjectsInGrid.Add(o); }
Property Type, как и колонка Type пока пустые. когда пользователь добавил все объекты, он выделяет в гриде один или несколько объектов и в комбобоксе выбирает тип.
На событие SelectionChanged комбобокс находит по id элемент в листе-сорсе и заполняет проперти Type.
Я только начала работать с WPF, но предполагаю, что там есть возможность как-то "связать" колонку типа и комбобокс нормальным способом, а не как у меня вручную.
В моем подходе мне не нравится:
Событие SelectionChanged срабатывает, когда меняется выделенный айтем, но если я выбираю другой объект и мне нужно для него поставить такой же тип как и в прошлом - оно не генерится. Хотелось бы сделать все на более высоком уровне. Гуглила, искала, но ничего конкретного для выполнения этой задачи не нашла.


Ответ

Окей, судя по всему, вам нужно вот что:




Вроде бы code-behind не нужен вовсе. Но вам нужно установить правильный DataContext

Да, ещё одна проблема вашего кода: ваша ViewModel (то есть, класс, к которому будет Binding), а именно, класс ObjectInGrid, не реализует интерфейс INotifyPropertyChanged. Это важно, обязательно имплементируйте его. Иначе работать не будет.

Visual Studio 2012, C#, Compiler Options

Привет. Как скомпилировать проект C# с оптимизацией по размеру, и как скомпилировать с оптимизацией по скорости? Спасибо


Ответ

Среди ключей компилятора C# есть лишь один, относящийся к оптимизации: /optimize
Таким образом, вы не можете управлять оптимизацией, вы можете лишь включить или выключить её.
Это относится не только к Visual Studio 2012, но и к версиям с Visual Studio .NET 2003 вплоть до текущей Visual Studio 2015.

Конструктор по умолчанию

class A { public: A():a(0),b(0) {} explicit A(int x): a(x), b(0) {} A(int x, int y): a(x), b(y) {} private: int a,b; };
и
class A { public: explicit A(int x=0, int y=0): a(x), b(y) {} private: int a,b; };
Есть ли различия? Что лучше использовать?


Ответ

Эти два объявления классов не эквивалентны.
Во втором объявлении класса конструктор объявлен со спецификатором функции explicit, а это ограничивает применение этого конструктора в различных ситуациях.
В первом же объявлении класса только конструктор преобразования объявлен со спецификатором функции explicit. А это означает, что другие конструкторы вы можете вызывать неявно.
То есть первое объявление предоставляет больше возможностей по использованию класса.
Рассмотрите следующую демонстрационную программу
#include
struct A { explicit A( int x = 0, int y = 0 ) : x( x ), y( y ) {} int x; int y; };
struct B { B() : x( 0 ), y( 0 ) {} explicit B( int x ): x( x ), y( 0 ) {} B( int x, int y ): x( x ), y( y ) {} int x; int y; };
void f( const A &a ) { std::cout << "a.x = " << a.x << ", a.y = " << a.y << std::endl; }
void g( const B &b ) { std::cout << "b.x = " << b.x << ", b.y = " << b.y << std::endl; }
int main() { // f( {} ); // f( { 1, 2 } );
g( {} ); g( { 1, 2 } ); }
Ее вывод на консоль:
b.x = 0, b.y = 0 b.x = 1, b.y = 2
В этой программе два вызова функции f закомментированы, так как если их раскомментировать, то компилятор выдаст сообщение об ошибке.
Другое важное отличии состоит в том, что один класс имеет всего лишь один конструктор с заданной сигнатурой, а другой класс имеет три конструктора с различными сигнатурами.
Рассмотрите еще один демонстрационный пример
struct A { explicit A( int x = 0, int y = 0 ) : x( x ), y( y ) {} int x; int y; };
struct B { B() : x( 0 ), y( 0 ) {} explicit B( int x ): x( x ), y( 0 ) {} B( int x, int y ): x( x ), y( y ) {} int x; int y; };
struct C { //friend A::A(); friend B::B(); };
int main() { }
Здесь в классе C вы можете объявить конструктор по умолчанию класса B в качестве друга класса С. Однако вы не можете сделать то же самое с конструктором по умолчанию класса A, чтобы объявить его другом класса C, так как конструктор по умолчанию в классе A имеет другую сигнатуру.
Вам уже придется писать
struct C { friend A::A( int, int ); };
а это может быть не тем, что вы хотели бы получить. То есть если вы, например, хотели, чтобы другом был конструктор, который вызывается исключительно без аргументов.
То есть, опять-таки, когда имеются отдельные конструкторы, то ваши возможности более широкие.
Если рассматривать не конструкторы, а функции, то разница имеется еще более существенная.
Аргументы по умолчанию не влияют на тип функции. Поэтому, например, если вы объявили функцию как
void f( int, int = 0 );
то, несмотря на аргумент по умолчанию и того факта, что вы можете ее вызывать как
f( value );
тем не менее ее тип void( int, int ). А это в свою очередь означает, что вы не можете, например, написать
void h( void f( int ) ) { f( 10 ); }
void f( int x, int y = 0 ) { std::cout << "x = " << x << ", y = " << y << std::endl; }
//
h( f );
так как параметр функции h имеет тип void( int )., а у функции, используемой в качестве аргумента, тип void( int, int )
Если же вы объявите две функции вместо одной
void h( void f( int ) ) { f( 10 ); }
void f( int x ) { std::cout << "x = " << x << std::endl; } void f( int x, int y ) { std::cout << "x = " << x << ", y = " << y << std::endl; }
то данный вызов
h( f );
будет корректным, так как имеется функция с одним параметром.

Покупка сертификата для связи WCF

В течение долгого времени я использую "Makecert.exe", чтобы создать свой собственный сертификат, используемый для связи WCF между двумя клиентами. Но я получаю отчеты об ошибках от пользователей, которые имеют более высокие процедуры безопасности/проверки, ошибки похожие на это:
UntrustedRoot: A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider
Я хочу избавиться от этого и приобрести сертификат. Предпочтительно с очень длинным срока годности. Но у меня остались вопросы:
Какой тип сертификата мне нужен? (Какое имя у этого типа сертификата?) Где я могу купить это? Я был бы признателен, по крайней мере за одну строку о том, как я могу проверить тип сертификата.
Используется Tcp и Pipe биндинги(в них и прописан сертификат) с поддержкой сессий на основе callback вызовов. Приложение у меня десктопное(сервер-много клиентов), тоесть это не веб сайт, я передаю информацию между двумя приложениями.


Ответ

Если используется http binding, то с серверной стороны должно хватить обычного single-domain https сертификата - т.к. от сервера при этом требуется лишь сертификат с
Enhanced Key Usage: Server Authentication (1.3.6.1.5.5.7.3.1)
Обычные провайдеры сертификатов добавляют еще и Client Authentication (1.3.6.1.5.5.7.3.2).
Проверить, хватит или нет, можно сгенерировав такой сертификат самому:
makecert -r -pe -n "CN= myserver " -b 01/01/2000 -e 01/01/2050 -eku 1.3.6.1.5.5.7.3.1 -ss my -sr localMachine -sky exchange -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12
Если с ним приложение заработает - то заработает и с сертификатом от https провайдера.

С помощью Jsoup спарсить данные из определенной родительской ветки


При парсинге страницы в Андроид приложение (пользую последнюю версию либ от Jsoup.org), выбираю только дочерние элементы(Выбираются все элементы, которые на схеме выделены розовым), а можно как нибудь выбрать сначала дочерние элементы с первого родителя, а потом только со второго и т.д.Как это примерно реализовать?


Ответ

Очевидное решение с выбором родительских элементов и последующим поиском детей в них.
public static void main(String[] args) { String html = "" + "" + " Try jsoup" + "" + "" + "

" + "

child1.1

" + "

child1.2

" + "

child1.3

" + "
" + "
" + "

child2.1

" + "

child2.2

" + "

child2.3

" + "
" + "
" + "

child3.1

" + "

child3.2

" + "

child3.3

" + "
" + "
" + "
" + "" + "";
Document doc = Jsoup.parse( html );
Elements parents = doc.select( "div" ); // выбор родителей System.out.printf( // можно выбрать элемент по индексу "parent[%d]: %s#%s%n", 2, parents.get( 2 ).tagName(), parents.get( 2 ).id() );
for ( Element parent : parents ) { System.out.printf( "parent: %s#%s%n", parent.tagName(), parent.id() ); for ( Element child : parent.select( "p" ) ) { // выбор внутри родителя System.out.println( child.text() ); } } }
Выведет:
parent[2]: div#parent3 parent: div#parent1 child1.1 child1.2 child1.3 parent: div#parent2 child2.1 child2.2 child2.3 parent: div#parent3 child3.1 child3.2 child3.3 parent: div#parent4
Используя псевдоселектор :has(selector), можно выбрать только те
, в которых есть


Elements parents = doc.select( "div:has(p)" );
Тогда в выдачу не попадет #parent4

Структура файла .class

Какую информацию можно получить от уже скомпилированного java файла .class? Какие данные там хранятся в явном виде?


Ответ

Если я ничего не забыл и правильно понимаю официальную документацию (https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html), хранятся там в явном виде все строки, информация о предке, методах, интерфейсах и полях. Может и еще что.

Не работает текстовая/видео реклама admob

Обычный баннер работает, а контекстовая реклама и видео не работает(межстраничное объявление). Вообще пустое место ничего вообще не показывает.
main_activity
AdView mAdView = (AdView) findViewById(R.id.adView); AdRequest adRequest = new AdRequest.Builder().build(); mAdView.loadAd(adRequest);
main.xml
// мой код


Ответ

Видео и межстраничная реклама могут работать только в больших View. У вас же баннер маленький (ads:adSize="BANNER") и они там не поместятся. Засим вам надо или как тут создать отдельную AdView для этих типов реклам или вообще не создавать для них отдельного View, а доверить их создание самому adMob-у, как показано в официальной документации по Interstitial Ads
Также проверьте, что эти типы рекламм включены в вашем аккаунте как показано тут

ImageView и покрывающий его круглый прозрачный градиент

Дано:
ImageView, в который загружена круглая .png картинка.
Как программно добавить поверх картинки круглый градиент из drawable.xml ?
При этом сквозь градиент должно быть видно картинку.
UPD:
ImageView я добавляю на экран кодом:
linearLayout.addView(imageView)
При клике на ImageView нужно, чтобы появился прозрачный градиент в этом ImageView и через определенное время убрался.
По идеи можно прописать все ImageView(их 50, кол-во не меняется) в layout'е и обернуть ImageView в какой нибудь lаyout, добавив в него еще одну ImageView с градиентом, которую я буду делать визибл при нажатии.
На сколько плохо такое решение будет ?
Код как я добавляю картинки:
LinearLayout layout = (LinearLayout) findViewById(R.id.ll); for (int i = 0; i < 50; i++) { ImageView imageView = new ImageView(this); imageView.setId(i); imageView.setPadding(0, 0, 8, 0); imageView.setImageBitmap(BitmapFactory.decodeResource( getResources(), R.drawable.pic1)); imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE); layout.addView(imageView); }


Ответ

Согласно en-SO делается это с помощью android:type="radial" так:

Прозрачность при этом делается проставлением значений альфа-канала в цвете. Это первые две цифры.
При этом, чтобы градиент был сверху изображения можно
Использовать selector картинку поместить в фон, а градиент как изображение ImageView Или наложить поверх ImageView ещё один ImageView, в коий и поместить градиент любым способом. Извратиться, перевести оба изображения в BitMap и наложить попиксельно)

Моментальное выполнение в timeout

Показали код из сторонней библиотеки. Какие тонкие моменты могли заставить автора в таймауте поставить время ноль?
setTimeout(function () { //todo something }, 0);


Ответ

Этот способ может понадобиться, если потребуется асинхронное выполнение кода.
Например
console.log("1"); console.log("2"); console.log("3");
выведет, как и предполагается: 1 2 3
Однако, при добавлении setTimeout получится: 1 3 2
console.log("1"); setTimeout(function() { console.log("2"); }, 0); console.log("3"); // > 1 3 2
Это связано с тем, что выполнение функции откладывается до следующего витка event loop.

Отменить оплату со внутреннего счета

IncludeComponent("bitrix:sale.order.ajax", "uni_sale_order_ajax", Array( "PATH_TO_BASKET" => "/personal/cart/", // Страница корзины "PATH_TO_PERSONAL" => "/personal/order/", // Страница персонального раздела "PATH_TO_PAYMENT" => "/personal/order/payment/", // Страница подключения платежной системы "PATH_TO_AUTH" => "/personal/profile/", // Страница авторизации "PAY_FROM_ACCOUNT" => "N", // Позволять оплачивать с внутреннего счета "COUNT_DELIVERY_TAX" => "N", // Рассчитывать налог для доставки "COUNT_DISCOUNT_4_ALL_QUANTITY" => "N", // Рассчитывать скидку для каждой позиции (на все количество товара) "ONLY_FULL_PAY_FROM_ACCOUNT" => "N", // Позволять оплачивать с внутреннего счета только в полном объеме "ALLOW_AUTO_REGISTER" => "N", // Оформлять заказ с автоматической регистрацией пользователя "SEND_NEW_USER_NOTIFY" => "N", // Отправлять пользователю письмо, что он зарегистрирован на сайте "DELIVERY_NO_AJAX" => "Y", // Рассчитывать стоимость доставки сразу "DELIVERY_NO_SESSION" => "N", // Проверять сессию при оформлении заказа "TEMPLATE_LOCATION" => ".default", // Шаблон местоположения "DELIVERY_TO_PAYSYSTEM" => "d2p", // Последовательность оформления "SET_TITLE" => "Y", // Устанавливать заголовок страницы "USE_PREPAYMENT" => "N", // Использовать предавторизацию для оформления заказа (PayPal Express Checkout) "PROP_1" => "", // Не показывать свойства для типа плательщика "Физическое лицо" (s1) "PROP_2" => "", // Не показывать свойства для типа плательщика "Юридическое лицо" (s1) ), false );
?>
вроде правильно, но оплачивается со внутреннего счета. Я даже в шаблоне template.php закомментировала строку //include($_SERVER["DOCUMENT_ROOT"].$templateFolder."/paysystem.php");
UPD
$arParams["PAY_FROM_ACCOUNT"] ="N" ; $arParams["COUNT_DELIVERY_TAX"] ="N"; $arParams["COUNT_DISCOUNT_4_ALL_QUANTITY"] = "N"; $arParams["ONLY_FULL_PAY_FROM_ACCOUNT"] ="N"; $arParams["DELIVERY_NO_AJAX"] = (($arParams["DELIVERY_NO_AJAX"] == "Y") ? "Y" : "N"); $arParams["USE_PREPAYMENT"] = $arParams["USE_PREPAYMENT"] == 'Y' ? 'Y' : 'N'; $arParams["DISPLAY_IMG_HEIGHT"] = Intval($arParams["DISPLAY_IMG_HEIGHT"]) <= 0 ? 90 : Intval($arParams["DISPLAY_IMG_HEIGHT"]); $arParams["DISPLAY_IMG_WIDTH"] = Intval($arParams["DISPLAY_IMG_WIDTH"]) <= 0 ? 90 : Intval($arParams["DISPLAY_IMG_WIDTH"]);
Я поменяла в самом родном компоненте битрикса. Ничего не получилось.
UPD от 21.12
if($arResult["USER_VALS"]["CONFIRM_ORDER"] == "Y") { if(strlen($arResult["REDIRECT_URL"]) > 0) { ?>


Ответ

Оплата с аккаунта если отключена опция PAY_FROM_ACCOUNT не будет работать, скорее всего 2 варианта надо искать
вы смотрите не тот компонент В каком-то из локальных модулях или в init.php созданы события на оформление покупки в которых вручную применен метод CSaleUserAccount::Withdraw или CSaleUserAccount::Pay

jquery обращение к элементу [дубликат]

На данный вопрос уже ответили: Не работает append() 1 ответ Jquery как обратиться к элементу с id="xfield[price]" Делаю вот так ничего не происходит
$(function() { alert($("#xfield[price]").val()); });


Ответ

Попробуйте вот так:
$(function() { alert($("#xfield\\[price\\]").val()); });
UPDATE
Я в таких случаях использую функцию для escaping.
function escapeSelector(selector) { if (!selector) return false; var specials = [ '#', '&', '~', '=', '>', "'", ':', '"', '!', ';', ',' ]; var regexSpecials = [ '.', '*', '+', '|', '[', ']', '(', ')', '/', '^', '$' ]; var sRE = new RegExp( '(' + specials.join('|') + '|\\' + regexSpecials.join('|\\') + ')', 'g' );
return selector.replace(sRE, '\\$1'); }
В Вашем варианте это должно работать вот так:
$(function() { alert($("#" + escapeSelector("xfield[price]")).val()); });
Попробуйте. Сработает - дарю ;)
UPDATE 2
@Igor также предоставил код, работающий на чистом javascript
alert(document.getElementById("xfield\[price\]").value);

Загрузить файл csv через php

При нажатии на кнопку необходимо сформировать и загрузить файл с данными в формате csv.
Есть такая функция function getCsvFile(...)
Данные формируются и файл с данными сохраняется на сервере. Но мне необходимо, чтобы его мог получить клиент через загрузку.
Подскажите, пожалуйста, что не так.
Заранее благодарен
$now = gmdate("D, d M Y H:i:s"); header("Cache-Control: max-age=0, no-cache, must-revalidate, proxy-revalidate"); header("Last-Modified: {$now} GMT"); header("Content-Type: application/force-download"); header("Content-Type: application/octet-stream"); header("Content-Type: application/download"); header("Content-Disposition: attachment;filename=test.csv"); header("Content-Transfer-Encoding: binary");
//$array = $this->getLinks(...); $titles = array("id", "Test"); ob_start(); $df = fopen("test.csv", "w"); fputcsv($df, $titles, ';');
$data = array( array(1,2), array(1,2), array(1,2), array(1,3) );
foreach ($data as $row) { fputcsv($df, $row, ';'); } fclose($df);


Ответ

По идее Content-Type должен быть один. И в значении для csv надо указать text/csv
header("Content-type: text/csv");
Пример - тут

Как сократить запись на JS - привести в нормальный вид (присвоение порядковых номеров)

Подскажите, пожалуйста, способ привести код jquery в нормальный вид:
$('.go0').click(function(){ carousel.trigger('owl.goTo', 0) });
$('.go1').click(function(){ carousel.trigger('owl.goTo', 1) });
$('.go2').click(function(){ carousel.trigger('owl.goTo', 2) });
$('.go3').click(function(){ carousel.trigger('owl.goTo', 3) });
$('.go4').click(function(){ carousel.trigger('owl.goTo', 4) });
$('.go5').click(function(){ carousel.trigger('owl.goTo', 5) });
$('.go6').click(function(){ carousel.trigger('owl.goTo', 6) });
$('.go7').click(function(){ carousel.trigger('owl.goTo', 7) });
$('.go8').click(function(){ carousel.trigger('owl.goTo', 8) });
Элементов (.go0, .go1 и т.д.) может быть бесконечно много, и писать их в таком виде не нормально.
К сожалению, не нашел как записать это в виде с n+1 или типа того.


Ответ

Решение "не включая мозг":
for (var ix = 0; ix < 9; ix += 1) { $('.go' + ix).click(function (ix) { return function() { carousel.trigger('owl.goTo', ix); }; }(ix)); }
Теперь нормальное решение:
Обычно у элементов переключения карусели общий предок и сами элементы идут в нем подряд. Поэтому достаточно найти номер потомка у предка, что в jQuery тривиальная задача. Предположим что у всех переключателей установлен класс go
$('.go').click(function() { carousel.trigger('owl.goTo', $(this).index()); });
Если элементы .go находятся еще каждый в своей обертке, то вместо $(this) нужно будет указать предка, положение которого в пределах своего предка может дать номер слайда.

Как вложить класс в метод?

Есть кусок кода на java
final List advertisements = new ArrayList<>(); new Object() { public void recurse(int i) { advertisements.add(storage.list().get(i)); if (i + 1 < storage.list().size()) recurse(i + 1); } }.recurse(0);
предполагается копирование элементов листа из storage.list() в advertisements таким вот способом, но почему-то по отработке кода лист пустой, что может быть не так?


Ответ

Сложно сказать, почему у Вас что-то не работает. Возможно, проблема в другом коде, который мы не видим. Однако, на одну неточность можно указать сразу - всегда выполняется storage.list().get(0) без проверки списка на непустоту. Это может привести к исключению.
Если же рассматривать идею, то она вполне работоспособная. Вот немного изменённый работающий код:
import java.util.List; import java.util.ArrayList;
class Test { public static void main(String [] args) { final List list1 = new ArrayList<>(); final List list2 = new ArrayList<>();
list1.add("String 1"); list1.add("String 2"); list1.add("String 3");
new Object() { public void recurse(final int i) { if (i < list1.size()) { list2.add(list1.get(i)); recurse(i + 1); } } }.recurse(0);
System.out.println("List 1:"); for (final String s : list1) System.out.println("\t" + s);
System.out.println("List 2:"); for (final String s : list2) System.out.println("\t" + s); } }
Вывод программы:
List 1: String 1 String 2 String 3 List 2: String 1 String 2 String 3

Изменение input'a переменной из PHP через JS

Необходимо заменить текст input'a текущей датой, получаемой из PHP. Вот код, при нажатии input заполняется как undefined. Где ошибка?
PHP:
$today = getdate(); $nowdate = $today['mday']." ".$today['month']." ".$today['year']." ".$today['hours'].":".$today['minutes'].":".$today['seconds'];
HTML:

JS:
function current(el) { document.getElementById('date').value = el; }


Ответ

Для того, чтобы отобразить переменную php в коде, нужно использовать echo или конструкцию вида , которая является сокращением от echo
Т.е. переменную необходимо выводить так: или так
Так как в вашем случае это значение строковое, то его нужно выводить в кавычках. Следовательно обработчик onclick будет выглядеть так: onclick="current('')"
Также, если php код и html располагаются в одном файле, то код php должен находится выше представленного html
Для контроля ошибок всегда можно использовать консоль браузера. Если в коде имеется javascript, то на некоторые ошибки в коде он реагирует отказом в работе. Соответственно, узнать причину можно открыв консоль и посмотреть причину ошибки. Как правило Она указывает на место в коде, где произошла ошибка и причину.

saveToCassandra() : IllegalArgumentException: Multiple constructors with the same number of parameters not allowed

Что я делаю не так? Здесь выдаёт ошибку при запуске:
textfile.saveToCassandra("logs", "logstable")
Весь код:
object App extends java.io.Serializable {
final val APP_NAME = "SparkBatchTest"
def main (args: Array[String]) {
val conf = new SparkConf().setAppName(APP_NAME).setMaster("local[2]") .set("spark.cassandra.connection.host", "localhost") .set("spark.cassandra.connection.native.port", "9042") val sc = new SparkContext(conf)
val textfile = sc.textFile("hdfs:////tmp/kafka/test/15-12-10/FlumeDat*")
textfile.foreach(record => seperateFields(record)) textfile.saveToCassandra("logs", "logstable") //здесь ругается
}
def seperateFields(line: String): Tuple5[Object, Object, Object, Object, Object] = { println("Waiting...") Thread sleep 3000 println("Saving...") val split = line.split(" ").toArray[Object] println(line) return (split(0) + " " + split(1), if (line contains "Down") "0" else "1", split(5), split(6), split(4)) } }
Перед форматированием содержание файла следующее:
2015-12-10 12:04:48.299 AMP (amp-management-5-sa)[6953]: Aruba RAP-109 a63253686jypmO68380 Down System Device ID: 2490 Top > mariscos puerto vallarta 2-Standard
таблица в Cassandra выглядит следующим образом:
datetime | location | logid | status | systemid ---------------------+----------+---------+---------------------+---------- 2015-12-23 15:10:01 | 1 | RAP-109 | a73225704jypmO54359 | Aruba 2015-12-23 15:55:54 | 0 | RAP-109 | a62710684jypmO66318 | Aruba 2015-12-23 15:10:02 | 1 | RAP-109 | a2222705jypmO69412 | Aruba 2015-12-23 15:09:45 | 1 | RAP-109 | a80296226jypmO21003 | Aruba 2015-12-23 15:25:29 | 1 | RAP-109 | a11170884jypmO9634 | Aruba 2015-12-23 15:55:53 | 1 | RAP-109 | a18255961jypmO91299 | Aruba 2015-12-23 16:17:27 | 1 | RAP-109 | a41956492jypmO85560 | Aruba


Ответ

Решено, переписал следующие строки:
val textfile = sc.textFile("hdfs:////tmp/kafka/test/15-12-10/FlumeDat*")
val res = sc.parallelize(Seq(seperateFields(textfile.first()))) res.saveToCassandra("logs", "logstable", SomeColumns("datetime","location","logid","status","systemid"))
и ещё тут чуть-чуть:
def seperateFields(line: String): Tuple5[String, String, String, String, String] = {...
и всё заработало!

Как можно наследовать фабрику?

Есть такого вида фабрика, как ее можно наследовать?
appServices.factory('Parent', ['$resource', '$rootScope', function ($resource, $rootScope) { var service = function () { this.items = []; } service.prototype.load = function (query) {} service.prototype.update = function (query) {} service.prototype.delete = function (query) {} return service; } ]);


Ответ

Сервис и фабрика это разные понятия в мире Angular. Фабрику, которая у вас в примере, как раз таки можно пронаследовать, т.к. она возвращает непосредственно саму функцию конструктор, которой достаточно для наследования. Сервис же при инициализации создаст экземпляр родителя.
.factory('ParentFactory', function () { var Parent = function () { this.items = []; } Parent.prototype.load = function (query) {} Parent.prototype.update = function (query) {} Parent.prototype.delete = function (query) {} return Parent; }) .factory('ChildFactory', function (ParentFactory) { var Child = function () { // инициализация родителя, если необходима ParentFactory.call(this); // свои свойства this.limit = 10; } // наследование Child.prototype = Object.create(ParentFactory.prototype); Child.prototype.constructor = Child;
// свои методы Child.prototype.insert = function (query) {}
return Child; })
Пример на Plunker

Получение доступа(взлом) к роутеру

Вопрос, наверное, вечный. Конечно я понимаю что я далеко не первый кто это задает, но я до сих пор не до конца понял как все работает. Я обнаружил что есть много способов добиться доступа к вражескому роутеру такими неэффективными сегодня способами как брутфорс и тупой подбор паролей по словарю, более продвинутые пошли посредством перехвата хендшейков и подбора совпадений уже на локальном устройстве, что в сотни или даже тысячи раз быстрее, но менее надежно, но ведь это далеко не самый выгодный вариант. Наиболее продвинутые хакеры явно могут как-то провести DDoS атаку на роутер, что назвали, как я прочитал, DNS Amplification, но я не нашел как такие атаки проводят. Что они используют для проведения таких атак, подробный мануал на их проведение, подробный мануал по защите от них..
Я, вероятно, не прав в чем-то, тогда подскажите какие варианты атак на роутер могут быть произведены еще и ресурс на подробности в придачу.
И еще, я не уверен что обратился на тот ресурс сети stackoverflow, если это так - не вините сильно, я не нашел более правильного за тематикой.


Ответ

Не претендую на полноту, но добавлю к этому списку уязвимости в ПО роутера (несколько примеров можно видеть, например, в статье "Как взламывали и защищали сети в 2014 году" от Positive Technologies (PT)), а также использование бэкдоров (тоже приведена ссылка как пример, ибо "их есть" почти у каждого производителя). Вот в этой статье от PT "СТАТИСТИКА УЯЗВИМОСТЕЙ КОРПОРАТИВНЫХ ИНФОРМАЦИОННЫХ СИСТЕМ 2014" можно встретить такие векторы атак, как недостатки конфигурации SSL. Пересказывать содержание ссылок не считаю целесообразным, поскольку назвал направления, а технических деталей там очень много.
Припоминается еще атака в виде посылки на роутер (и другие устройства) специально сформированного пакета с инженерной информацией, дающей полный доступ к устройству, но к сожалению не вспомню названия (а детали тем более, т.к. специфичны для каждого производителя).
Можно вспомнить еще такие детские болезни, как логины и пароли в админке по умолчанию, но это, скорее, подмножество словарных паролей.

Запуск ещё одной копии приложения программно

Можно ли как-то программно, в ответ на нажатие кнопки формы, открыть ещё одну копию приложения, как если просто открыть .exe-файл?


Ответ

Попробуйте так:
Process.Start(Application.ExecutablePath);

Это решение специфично для Windows Forms. Более общее решение — использовать рефлексию для нахождения пути:
Assembly.GetEntryAssembly().CodeBase
Этот вызов вернёт URI-строку наподобие
file:///C:/Program Files/YourProgram/YourProgram.exe
которую можно скормить в Process.Start. Если вы всё же хотите путь с привычным синтаксисом, примените конструкцию
new Uri(Assembly.GetEntryAssembly().CodeBase).LocalPath
которая вернёт обыкновенный адрес наподобие
C:\Program Files\YourProgram\YourProgram.exe

спецификаторы inline __inline __forceinline

Есть ли отличия в скорости работы кода, если например использовать спецификатор в методе класса?


Ответ

Есть, иногда.
inline не имеет никакого отношения к встраиванию функций, все компиляторы ее игнорируют. По этому единственное практическое применение inline - это использовать ее для функций, определенных в заголовочных файлах:
// header.hpp inline void f() { // несколько экранов кода }
Такая функция f возможно никогда не будет заинлайнена, но без inline ее нельзя разместить в заголовочном файле.
__inline, __forceinline, и другие расширения компилятора уже могут как-то влиять на то, будет функция заинлайнена или нет. Однако в общем случае встраивание функции не приводит к увеличению производительности. После встраивания функции, производительность может как увеличиться (убрали вызов функции), так и уменьшиться - цикл может стать большим, и перестанут работать предсказания в процессоре (prefetch и т.п.).
По этому __inline и __forceinline следует применять совместно с бенчмарками, использованием профилировщика, и просмотром сгенерированного ассемблерного кода. Использование этих ключевых слов вслепую не дает никакого эффекта.

Почему условия не работает?

Почему bot не угадывает число, если даже цифры совпадают?
import random
coin = input("Number:") bot = 0 bot = random.randint(1, 2) if coin == bot: print("bot угадал") else: print("bot НЕ угадал") print(bot) input("

Enter")


Ответ

type(coin) #
Подробно
Функция input() возвращает строку. Предположим в ответ на запрос мы ввели в консоль 1, тогда значение переменной coin будет "1" - строка (str), первый символ которой 1
random.randint(1, 2) возвращает число, в результате значение переменной bot - число (int)
Соответственно, когда мы сравниваем две эти переменные (coin == bot) то получаем False в любом случае. Строка "1" никак не равна числу 1
Вам нужно привести типы переменных друг к другу, например: coin == str(bot), так мы будем сравнивать строку и строку

MVC для игры морской бой

Разделил логику от интерфейса на составляющие MVC
Model:
Класс Game в котором реализованы игроки, у каждого игрока есть поле, корабли и так далее
View:
2 объекта класса TField (визуальный компонент)
Controller:
Класс GameController, который должен связывать логику игры и ходы с визуальным представлением на форме.
Именно на контроллере стал задумываться, как связать их. Определить в классе GameController объекты классов модели и визуального представления? Но как их связать? Обработку нажатия на клетку в поле, отправку координат X и Y в класс Game и обратно получить ответ, обработав попадание/не попадание?
Я частично понял, как реализовать все это. У нас есть цепочка:
Представление -> Контроллер -> Модель
Представление вызывает клик и отправляет контроллеру событие о выстреле. Контроллер передает информацию об это модели на обработку. Но как сделать обновление Представления после изменений в Модели я так и не понял.
Я так понимаю, что нужно создать слушателя/-ей, которые будут вызываться из Модели при обновлении данных. Но это значит, что Модель должна содержать ссылку на Представление, что по сути перечит MVC, если Модель должна не знать о Представлении. Есть мысли?


Ответ

Смотрите. Вам нужен по идее event или Listener, или как там этот паттерн называется.
Суть такова.
Модель выставляет метод Subscribe(), в который можно передать callback, который будет вызван при изменении свойства. Представление знает о модели, и подписывается на её изменения. Таким образом, модель ничего не знает о представлении, но может дёрнуть это самое представление, когда что-то поменялось.
Пример на коленке:
class Model { public: typedef int Token;
Token subscribe(std::function callback) { max_token++; callbacks[max_token] = callback; return max_token; }
void unsubscribe(Token token) { callbacks.erase(token); }
private: std::map> callbacks; Token max_token = -1;
// это дёрнет все callback'и void notifyall() { for (auto& kv : callbacks) kv.second(); } };

class View { Model* model; Model::Token token;
//... View(Model* model) : model(model) { token = model->subscribe([this] { OnModelUpdate(); }); }
~View() { model->unsubscribe(token); } };

Как разместить в одном активити 2 кнопки ToggleButton

Как добавить в активити еще один слушатель ToggleButton для второй кнопки? Вот как я использую одну кнопку (к сожалению, в учебниках обычно приводят примеры на одну кнопку)
public class XXX extends ActionBarActivity implements OnCheckedChangeListener { ToggleButton tbutton1;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_xxx); tbutton = (ToggleButton) findViewById(R.id.tbutton1); } //...
@Override public void onCheckedChanged(CompoundButton buttonView, boolean tg1) { if (tg1) { // ... }};


Ответ

Есть несколько способов, вот некоторые из них:
В каждый обработчик в качестве параметра приходит view для которого произошло данное событие. Следовательно у полученного view можно взять id и в зависимости от этого выполнить те или иные действия.
@Override public void onCheckedChanged(CompoundButton buttonView, boolean tg1) { switch(buttonView.getId()) {
case R.id.toggle1: //событие от первой кнопки, делаем А break;
case R.id.toggle2: //событие от второй кнопки, делаем Б break;
default: break; } } Для каждой view создавать обработчик как экземпляр анонимного класса
private OnCheckedChangeListener toggle1Listener = new OnCheckedChangeListener() { public void onCheckedChanged(CompoundButton buttonView, boolean tg1) { //делаем А } }
private OnCheckedChangeListener toggle2Listener = new OnCheckedChangeListener() { public void onCheckedChanged(CompoundButton buttonView, boolean tg1) { //делаем Б } }
//установка в методе onCreate() toggle1.setOnCheckedChangeListener(toggle1Listener); toggle2.setOnCheckedChangeListener(toggle2Listener);
UPD: забыл сказать что для второго случая нет необходимости реализовывать интерфейс OnCheckedChangeListener в Activity

Вытаскивается неправильное название из JSON

Решил вытащить из вк название транслируемой музыки, но вытаскивается непонятно что.

данный код выводит:
array(1) { ["response"]=> array(1) { [0]=> array(5) { ["uid"]=> int(87581621) ["first_name"]=> string(10) "РРіРѕСЂСЊ" ["last_name"]=> string(10) "Салий" ["status_audio"]=> array(9) { ["aid"]=> int(428001219) ["owner_id"]=> int(87581621) ["artist"]=> string(12) "Tim McIlrath" ["title"]=> string(20) "What Are We Gonna Do" ["duration"]=> int(243) ["url"]=> string(155) "http://cs6093.vk.me/u12493734/audios/e096207ea781.mp3?extra=_6PaUdWEu_HsCr-UwAUdiay52ru8uK5tb-F227ZyutTKfD0zs_VSfyASSSZcgPzEYV_-qX83P73xANaDDtBEHVsMby8dtvE" ["performer"]=> string(12) "Tim McIlrath" ["lyrics_id"]=> string(8) "89253366" ["album"]=> string(8) "68893982" } ["status"]=> string(0) "" } } } TWhT86
Где TWhT86 - это название исполнителя, хотя написано что ["artist"]=> string(12) "Tim McIlrath" Через print_r название отображается правильно, но я не могу обратиться именно к ["artist"]


Ответ

echo($info['response'][0]['status_audio']['artist']); // Автор echo($info['response'][0]['status_audio']['title']); // Трек

Github: не могу выложить из за ошибки LF , CRLF

Недавно начал изучать GitHub, столкнулся с такой проблемой: директория есть, файл там лежит, мои действия (как я выкладывал) на картинке. Файл сделал с помощью notepad++.
fatal: pathspec did not match any files
Что это?


Ответ

Проблема в окончании файла. На Win и Linux они различны.
Использовать что-то типо dos2unix или Swiss File Knife для преобразования, чтоб ошибка исчезла.
Или попробовать что-то такое:
git config core.autocrlf false

рекурсивный поиск и создание нового массива

Array( 254370, 254363 ), 254363 => Array( 254369 ), 254357 => Array( 254362, 254359 ), 254359 => Array( 254360 ), Array( 254357 ) );
Есть массив, нужно обойти рекурсивно и создать новый, например при выборе ключа 254362, получаем значения 254370, 254363 ищем полученные значения, как ключи вновь и т.д. Новый массив должен иметь структуру, как в примере, но без незатронутых ключей при поиске.
В настоящий момент есть код:
var_dump(get_childs($child_array, $id));
function get_childs($array, $id) { foreach ($array[$id] as $value) { $childs[$id] = $array[$id]; get_childs($array, $value); } return $childs; }
При его исполнении возникает ошибка ERR_CONNECTION_RESET


Ответ

Ваша процедура может зацикливаться на данных в которых 2 id будут указывать друг на друга. В вашем примере таких не видно, но надо учитывать, что в вашем массиве присутствует элемент, отсутствие номера у которого может вводить в заблуждение:
254363 => Array( 254369 ), ... 254359 => Array( 254360 ), Array( 254357 ) <-- Вы думаете это 0й элемент ? НЕТ - это следующий по номеру, за максимальным в вашем массиве Т.е. 254364
А процедура с защитой от циклов и исключением других ошибок, типа отсутствующих элементов массива и не объявленной переменной childs должна выглядеть примерно так:
Array( 254370, 254363 ), 254363 => Array( 254369 ), 254357 => Array( 254362, 254359 ), 254359 => Array( 254360 ), 254369 => Array( 253000 ), Array( 254357 ) );
var_dump(get_childs($arr, 254362));
function get_childs(&$array, $id) { static $childs=[]; static $allkey=[]; if(!array_key_exists($id,$array)) return false; foreach ($array[$id] as $value) { $childs[$id] = $array[$id]; if(!in_array($value,$allkey)) { $allkey[]=$value; get_childs($array, $value); } } return $childs; } ?>

Добавить тёмный фон вокруг View

Есть ли в Android способ добавить тёмный фон вокруг layout'а, перекрывающий все, кроме статус бара, не наследуясь от Dialog? Мне нужен такой же затемненный фон, какой бывает при открытии диалогов. Создание layout-подложки тоже не подходит, потому, что в данном случае не будет перекрыт ActionBar.


Ответ

Cоздание layout-подложки тоже не подходит, потому, что в данном случае не будет перекрыт ActionBar.
Можно попробовать заменить ActionBar на Toolbar. Потом создаете кастомный View для диалога наследуясь от FrameLayout и указываете темный фон и атрибуты для высоты и ширины match_parent, в таком случае весь экран будет перекрыт, в том числе и Toolbar
Вот пример как можно сверстать корневой layout






Группировка в MS SQL строк с полями где NULL

Как то можно сгруппировать это:
F1 F2 F3 -------------------------- 1 null null null 2 null null null 3 4 null null null 5 null null null 6
В это:
F1 F2 F3 ---------------- 1 2 3 4 5 6


Ответ

Если у вас всего чётко по три, то примерно так.
Данные:
declare @data table (row_num int, F1 int, F2 int, F3 int);
insert into @data values (1, 1, null, null) ,(2, null, 2, null) ,(3, null, null, 3) ,(4, 4, null, null) ,(5, null, 5, null) ,(6, null, null, 6) ;
Запрос:
;with data as ( select rn = row_num - 1, * from @data ) select F1 = max(F1), F2 = max(F2), F3 = max(F3) from data group by rn / 3;
Результат:
F1 F2 F3 ----------- ----------- ----------- 1 2 3 4 5 6
Порядок строк всё-же нужно определить - либо явно (как в примере), либо косвенно (с помощью функции row_number() over (order by ...)), иначе нет гарантии, что строки сгруппируются как надо.

Apache2 “пожирает память” при long poll запросах

Апач поедает память процессами при long poll запросах. Используется технология long poll, как в данном видео: http://www.screenr.com/SNH
Из-за цикла проверки времени при многократном обновлении страницы происходит плодение процессов апача и забивка памяти, поскольку maxClients на апаче стоит 256, то апач, перейдя границу - зависает. Помогает только перезапуск. На апаче стоит itk модуль. Php подключен как модуль апача.


Ответ

Используйте Nginx как прокси и еще лучше к нему поставить php-fpm вместо апача. Иначе maxClients надо ставить очень и очень большим, что в итоге все равно приведет к паденю апача при нагрузках.
Nginx хорошо работает с медленными клиентами и отлично справляется с нагрузками. В связке с апачем он его разгрузит. А в связке с php-fpm вы вообще забудете о головной боли ;)
UPD
А еще лучше на Веб-сокеты перейти. Скорость работы вырастет, а нагрузка упадет.

Как удалить временные архивы, скачанные pip?

Работаю в Ubuntu 14. Пытался поставить matplotlib командой типа pip install matplotlib, он не смог скомпилиться (логично, я потом выяснил что этот pip идёт к python 2.7, а для python3 нужен pip3). При установке pip скачивал архив, из которого потом распаковывал matplotlib, и я не уверен удаляет ли он этот временный архив после распаковки. В хелп лазил, чего-то полезного не нашёл. Можно ли заставить pip удалить скачанные им временные файлы?


Ответ

в pip, насколько я знаю, нет такой функции. Это можно сделать так:
Удалите папку .pip/cache Вы можете проигнорировать установленные пакеты - --ignore-installed В последних версиях pip (c 6, по-моему) есть опция --no-cache-dir

Аналог в LINQ для SELECT * FROM table1 INNER JOIN table2

Есть два объекта DataTable datatable1 и datatable2. Как получить на выходе результат LINQ запроса аналогичный SQL-ному SELECT * FROM table1 INNER JOIN table2 ON condition в новом объекте DataTable? Как делать сам INNER JOIN и даже OUTER JOIN ясно.
from table1 in datatable1.AsEnumerable() join table2 in datatable2.AsEnumerable() on (int)table1["anID"] equals (int)table2["anID"] select new { A = (int)table1["A"], B = (int)table1["B"], C = (int)table2["C"], D = (int)table2["D"] };
А вот как получить результат в новом DataTable, не перечисляя при этом поля пример не попадается.
P.S. Вопрос не о работе с БД, а о возможностях c# + linq


Ответ

Так как нужна именно DataTable, то первоначально нужно создать ее и добавить колонки. Судя из вопроса вы хотите добавить все колонки из первой таблицы и из второй. Для этого можно воспользоваться следующим кодом.
DataTable table = new DataTable();
foreach(DataColumn column in table1.Columns){ table.Columns.Add("table1_"+column.ColumnName, column.DataType) } foreach(DataColumn column in table2.Columns){ table.Columns.Add("table2_"+column.ColumnName, column.DataType) }
Теперь в новой таблице колонки из обеих таблиц и можно добавлять строки.
var rows = from table1 in datatable1.AsEnumerable() join table2 in datatable2.AsEnumerable() on (int)table1["anID"] equals (int)table2["anID"] select table1.itemArray.Concat(table2.itemArray);
Получили список массивов которые можно добавлять в DataTable.
foreach(var row in rows){ table.Rows.Add(row); }
В итоге получили table со всеми нужными строками.

Ошибка “Ссылка на объект не указывает на экземпляр объекта”

program One;
var n: integer; a: array of array of integer; i, j: integer;
begin read(n); SetLength(a, n); for i := 1 to n do for j := 1 to n do read(a[i, j]); end.
Почему возникает ошибка?
Ссылка на объект не указывает на экземпляр объекта


Ответ

Вы выделили память только под первое измерение, надо так же выделять под второе
program One;
var n: integer; a: array of array of integer; i, j: integer;
begin read(n);
SetLength(a, n); // выделили под количество строк
for i := 0 to n-1 do // индексация в динамических массивах с нуля begin SetLength(a[i], n); // выделили под количество столбцов for j := 0 to n-1 do read(a[i][j]); end;
end.

Как передается ссылка на экземпляр класса в Java?

У меня есть класс Class1, в котором я храню какую-то свою информацию.
В классе активити А я создаю экземпляр своего класса Class1 cl1 = new Class1(), заполняю данными и передаю эту ссылку в класс следующей активити ActivityB actB.cl2 = cl1
В классе активити B поле cl2 статичное, и доступ к нему внутри пакета. Активити А рано или поздно уничтожится системой. Тогда что будет с полем cl2?


Ответ

В Java всё передается по значению без исключений. В данном случае будет передана ссылка на объект по значению. При уничтожении Активити А с объектом, на который ссылается cl1, ничего не произойдет, поскольку на него будет ссылаться объект cl2 из Активити B
Объект будет удален сборщиком мусора (GC), если до него не добраться из так называемых корневых объектов - это объекты, которые доступны вне Heap-памяти. К таким объектам относят все локальные переменные из стека, активные потоки, загруженные классы и другие. В процессе поиска мусора GC начинает обход с корневых объектов и постепенно спускаясь по дереву объектов отмечает их как "живые". Соответственно если объект не доступен ни из одного корневого объекта, то он будет удален.

Как перевести char в int, без изменения кодировки. Работа с StringBuffer

Задача моего метода- преобразовать каждое число типа StringBuffer в массив int.
При попытке преобразовать каждый символ "9 8 7 6 5 4 3 2 1 " с убранными пробелами я получаю результат: {57,56,55,54,53,52,51,50,49}
Как мне поместить в массив те же числа, что и в строке?
public static void main(String[] args){ StringBuffer strB = new StringBuffer("9 8 7 6 5 4 3 2 1 "); int arrInt=strBToArrInt(strB); for(int i=0;iint[] strBToArrInt(StringBuffer strBuff){ strBuff = new StringBuffer(strBuff.toString().replace(" ", "")); int[] arrInt =new int[strBuff.length()]; for (int i = 0; i < arrInt.length; i++) { arrInt[i]= Integer.valueOf(strBuff.charAt(0));//Я думаю -проблемма в кодировке. strBuff.deleteCharAt(0);//удаляю нулевой символ }
return arrInt; }//end strBToArrInt


Ответ

В твоём случае он возвращает ASCI-код символа. Тебе надо использовать метод digit. Замени
arrInt[i]= Integer.valueOf(strBuff.charAt(0));
На
arrInt[i]= Character.digit(strBuff.charAt(0), 10);
Но этот метод годен только для цифр. Если у тебя числа, то сначала надо разбить исходную строку на массив строк при помощи метода split
String []stringsArray=strBuff.toString().trim().split("\\s+");
А потом пройтись и распарсить каждую строку как число
int[] arrInt =new int[stringsArray.length()]; for (int i = 0; i < stringsArray.length; i++) { arrInt[i]= Integer.parseInt(stringsArray[i]); }