Страницы

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

пятница, 15 марта 2019 г.

c# jquery ajax сохранение pdf

Имеется метод в контроллере, который возвращает FileContentResult:
return File(pdfBytes, "application/pdf", "DownloadName.pdf");
Проблема в том, как с помощью jquery ajax в клиентской части получить и сохранить файл в формате pdf. Как решить данную проблему?


Ответ

Браузеры (и соответственно, jQuery) не умеют корректно сохранять файлы, приходящие в ответ на ajax-запрос.
Если файл нужно отдавать в ответ на POST-запрос и нужно поддерживать старые браузеры, то единственный надежный вариант - делать обычный полноэкранный POST.
Если файл нужно отдавать в ответ на GET-запрос, то достаточно просто заменить ajax вызов обычным GET-ом:
window.location.href = <ссылка на файл>;
Если в ответ на такое с сервера придет файл - он просто скачается, и пользователь останется на текущей странице.

В более новых браузерах файл, пришедший в ответ на ajax, можно сохранить через FileAPI. На всякий случай проверьте таблицу поддержки FileAPI - вдруг вам нужно поддерживать какой-нибудь IE9.
Решение через FileAPI (честно скопировано с enSO):
var xhr = new XMLHttpRequest(); xhr.open('POST', url, true); xhr.responseType = 'arraybuffer'; xhr.onload = function () { if (this.status === 200) { var filename = ""; var disposition = xhr.getResponseHeader('Content-Disposition'); if (disposition && disposition.indexOf('attachment') !== -1) { var filenameRegex = /filename[^;=
]*=((['"]).*?\2|[^;
]*)/; var matches = filenameRegex.exec(disposition); if (matches != null && matches[1]) filename = matches[1].replace(/['"]/g, ''); } var type = xhr.getResponseHeader('Content-Type');
var blob = new Blob([this.response], { type: type }); if (typeof window.navigator.msSaveBlob !== 'undefined') { // IE workaround for "HTML7007: One or more blob URLs were revoked by closing the blob for which they were created. These URLs will no longer resolve as the data backing the URL has been freed." window.navigator.msSaveBlob(blob, filename); } else { var URL = window.URL || window.webkitURL; var downloadUrl = URL.createObjectURL(blob);
if (filename) { // use HTML5 a[download] attribute to specify filename var a = document.createElement("a"); // safari doesn't support this yet if (typeof a.download === 'undefined') { window.location = downloadUrl; } else { a.href = downloadUrl; a.download = filename; document.body.appendChild(a); a.click(); } } else { window.location = downloadUrl; }
setTimeout(function () { URL.revokeObjectURL(downloadUrl); }, 100); // cleanup } } };
xhr.send($.param(params));

Активация кнопок в angular

Никак не могу сообразить.Есть несколько buttons на странице, как сделать так, что бы при клике по кнопке у нее появлялся класс active. Причем только у нее одной а не у всех.


Ответ

Это можно сделать так: у вас есть поле в модели selectedTab, по клику вы задаете текущее значение. Аналогично можно использовать другие удобные Вам идентификаторы.

Что такое bean в Spring

Не могу понять что такое Bean в википедии написано это как просто доменный объект, есть еще сервисы, контроллеры, DAO, что из них является бином и почему так называется, что я не так понимаю?


Ответ

В Spring-е бином (bean) называют любой класс, который управляется контейнером Spring. То есть такими вещами, как создание экземпляра бина, его инициализация, внедрение зависимостей и параметров, деинициализация, генерация всевозможных оберток над бином, занимается не ваш код, а IoC-контейнер Spring-а.

Как получить разницу между двумя датами для виджета?

Бросил курить 11 октября 2015 года, ровно в 15 часов 20 минут, бросил сигарету и сказал себе СТОП! По этому поводу решил для себя набросать виджет, что бы каждый раз при взгляде на главный экран телефона радовал меня моим крутым достижением!
Набросал проект виджета:

Как мне вместо "Вычисляю..." вывести сколько я уже не курю в формате: Лет Дней Часов Минут ?
Что нужно вставить вот в этот код:
public class MainActivity extends AppWidgetProvider {
final String LOG_TAG = "myLogs";
@Override public void onEnabled(Context context) { super.onEnabled(context); Log.d(LOG_TAG, "onEnabled"); }
@Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { super.onUpdate(context, appWidgetManager, appWidgetIds); Log.d(LOG_TAG, "onUpdate " + Arrays.toString(appWidgetIds)); }
@Override public void onDeleted(Context context, int[] appWidgetIds) { super.onDeleted(context, appWidgetIds); Log.d(LOG_TAG, "onDeleted " + Arrays.toString(appWidgetIds)); }
@Override public void onDisabled(Context context) { super.onDisabled(context); Log.d(LOG_TAG, "onDisabled"); }
}
СПАСИБО!


Ответ

Извиняюсь, пока что не могу прислать в нормальном виде кусок:
public static int getDifferenceTimeSeconds(int firstTimeHH, int firstTimeMM, int firstTimeSS, int secondTimeHH, int secondTimeMM, int secondTimeSS){ int firstTime = firstTimeHH*60*60+firstTimeMM*60+firstTimeSS; int secondTime = secondTimeHH*60*60+secondTimeMM*60+secondTimeSS; return firstTime - secondTime; }
public static int getDifferenceDateDays(Calendar firstDate, Calendar secondDate){ int firstDateDays = firstDate.get(Calendar.DAY_OF_YEAR); int secondDateDays = secondDate.get(Calendar.DAY_OF_YEAR); return firstDateDays - secondDateDays; }

Неопределенное поведение при определении/объявлении внешних глобальных констант

В книге "Программирование: принципы и практика использования С++" приводится следующий пример:
// file f1.cpp int x1 = 1; int y1 = x1+2; // y1 becomes 3
// file f2.cpp extern int y1; int y2 = y1+2; //UB, y2 becomes 2 or 5
То есть неизвестно, в каком порядке будут инициализированы глобальные переменные. Стоит ли ожидать аналогичного поведения при использовании глобальных констант?:
// file f1.cpp int x1 = 1; const int y1 = x1+2; // y1 becomes 3
// file f2.cpp extern const int y1; int y2 = y1+2; //UB???
И почему UB возникает вообще? Ведь переменная/константа во втором файле явно объявлена, но не инициализирована, а значит чтобы "узнать" её значение нужно обратиться к определению, а в этом случае y1 явно = 3. Ведь когда программа вызывает функцию, которая объявлена в первом файле, но определена во втором, она ведь не предполагает, что тело функции пусто (равно нулю), как это происходит в случае с внешними глобальными переменными.


Ответ

Во-первых, вы должны в файле f1.cpp указать, что константа имеет внешнее связывание
extern const int y1 = x1+2; // y1 becomes 3
иначе она будет не видна в файле f2.cpp, так как константы в C++ имеют внутреннее связывание.
Что касается вашего вопроса, то это не имеет значения, является ли переменная константой или нет. Проблема связана с тем, что не определен порядок инициализации статической памяти у модулей.
Что касается функций, то редактор связей просто проставляет адреса для внешних символов. К самим же функциям обращение идет во время выполнения. Поэтому, например, статические переменные функции инициализируются при вызове функции.

Virtualbox и исчезновение /boot/grub

Есть Windows 7 + Virtualbox и установленный Ubuntu Desktop 14. Эпизодически создаются снапшоты от Vbox. В Ubuntu постоянно происходят обновление системы, и в какой-то момент при следующей загрузке Ubuntu выдает ошибку error: file '/boot/grub/i386-pc/normal.mod' not found. По-настоящему, папка /boot/ пустая вообще.
Я пытаюсь переключиться на предыдущий снапшот, но ошибка та же, и даже самый первый образ тоже сломанный. То есть бэкапы я зря делал. За год такое уже повторилось 3 раза.
Почему могли исчезнуть данные из /boot/ ? Почему сломаны все раннее сделанные снапшоты и оригинал? Как можно это исправить, не начиная все с нуля?


Ответ

1, 2. похоже, что в каталог /boot у вас монтировался раздел, находящийся на другом виртуальном (или реальном) блочном устройстве (т.н. диске).
3. наиболее простой путь: найти «пропавший» раздел.
более сложный:
загрузить эту виртуальную машину с какого-нибудь другого образа (подойдёт практически любой установочный/live/«спасательный»/и т.п. от любого дистрибутива gnu/linux), подлкючив его как дополнительное блочное устройство примонтировать все необходимые разделы, начиная с корневого, в каталог (к примеру) /mnt скачать и скопировать в /mnt файл с пакетом с подходящей версией linux-а сделать chroot /mnt там, в chroot-е, установить пакет с linux-ом: dpkg -i файл на всякий случай (по идее эта команда должна выполниться в процессе установки пакета с linux-ом) выполнить ещё и update-grub выйти из chroot-а отмонтировать то, что монтировали, перезагрузить виртуальную машину без вспомогательного образа

Установка Windows и Linux на GPT диск и EFI

Как установить на один жесткий диск размеченный в GPT Windows и Linux запускающиеся в EFI?


Ответ

Обычно рекомендуется ставить сначала Windows затем Linux, собственно при таком раскладе обычно проблем не наблюдается. Если же у вас уже стоит Linux, и нужно установить Windows подойдет сл. хинт.
Во-первых, нужно озаботиться тем что бы для загрузки Linux вы использовали загрузчик совместимый с Windows, в моем случаи это был gummiboot. Далее ставим Windows (в моем случаи это была Windows 10, думаю на до 7ки включительно должно работать) как обычно, основная хитрость в диалоге разбивки диска (надеюсь там осталось немного места для Винды?) создаем под Windows раздел так чтобы на HDD не осталось неразмеченных областей, и говорим инсталлировать в него. На вопрос установщика о том что он хотел бы создать отдельный раздел под загрузчик ответить отрицательно. Кстати загрузчик Linux должен находиться в отдельном разделе.
Собственно в результате Windows благополучно установит свой загрузчик в раздел к загрузчику Linux и вы получите возможность использовать его в своем загрузчике или как было в мое случаи gummiboot его подхватывает автоматически.

Как передать имя таблицы в функцию как параметр?

Я использую Entity Framework. Есть некая функция, в которой происходит заполнение dataGridView данными из таблицы.
private void data() { using (Context context = new Context()) { var items = from Items in context.Table1 select Items;
dataGridView1.DataSource = items.ToList(); } }
Но я хочу сделать универсальную функцию, чтобы имя таблицы передавалось через параметр. Подскажите, как нужно модифицировать функцию, чтобы это стало возможным?
Что-то типа этого:
void Test() { data(tbl1); data(tbl2); }
private void data(SomeType tableName) { using (Context context = new Context()) { var items = from Items in tableName select Items;
dataGridView1.DataSource = items.ToList(); } }


Ответ

Если тип сущностей в таблицах одинаковый, то можно попробовать спустить функцию для выбора таблицы параметром:
void Test() { data(c => c.tbl1); data(c => c.tbl2); }
private void data(Func> tableSelector) { using (Context context = new Context()) { var items = from Items in tableSelector(context) select Items;
dataGridView1.DataSource = items.ToList(); } }
Если разный - добавьте генерик-параметр
private void data(Func> tableSelector) { using (Context context = new Context()) { var items = from Items in tableSelector(context) select Items;
dataGridView1.DataSource = items.ToList(); } }
в живую не проверял, возможны опечатки
Если нужно передавать имя таблицы именно как строку - придётся использовать reflection. Постарайтесь избегать этого :)

Как посмотреть автора строк SVN в PhpSorm

Есть видел в NetBeans такая фича по работе из SVN - показываются прямо в редакторе автора строк, чтобы увидеть кто что писал в PhpStorm нужно поставить плагин, нажать историю, нажать на номер конкретного коммита - просмотреть какие изменения вносились в этом коммите. Есть ли похожая штука в PhpStorm? (видеть автора строк)


Ответ

Обычно этот режим называется "blame" то есть поиск крайнего за сломаный код :)
В Php Storm эта штуковина спрятана под названием "annotate". Правый клац по файлу, Git > Annotate. Слева появится столбик с авторами, датами и комитами.
[правка] А, лол, вам SVN нужен. Ну там тоже этот annotate есть. Только не помню где. Нет на чем проверить :)

запустить apache после рестарта

выполняю в php скрипте
exec("sudo service apache2 restart", $output);
служба вырубается, но чтобы ее запустить надо делать это вручную в isp manager.
можно ли это сделать через php скрипт? почему служба не стартует по команде рестарта?
мягкий перезапуск reload в моей ситуации не помогает;
upd. даны права на запуск sudo из php- скрипта (www-data ALL=(ALL) NOPASSWD: ALL). т.е reload нормально отрабатывает, а restart по сути работает только как stop.


Ответ

Есть несколько вариантов перезапуска процесса - определяется версией операционки и сервера. Например, у меня работает:
sudo apachectl -k restart
Еще вариант:
sudo invoke-rc.d apache2 restart

Оптимизация алгортима перебора пикселей WPF C#

Здравствуйте, есть метод получения массива яркостей из BitmapSource для дальнейшего анализа:
public const float CoeffColor = ((float)100 / 255 * 3) / 10000; //... arrayPixelsImage = new byte[SizeArrayPixels]; source.CopyPixels(arrayPixelsImage, StriteImage, 0); //typeof(source) == BitmapSource float[,] massBrightness = new float[WidthImage, HeightImage]; Parallel.For(0, WidthImage, x => { for (int y = 0; y < HeightImage; y++) { int indx = y * WidthImage * 4 + 4 * x; float brightness = (float)(arrayPixelsImage[indx] + arrayPixelsImage[indx + 1] + arrayPixelsImage[indx + 2]) * CoeffColor; massBrightness[x, y] = brightness; } }); return massBrightness;
Интересует то, как можно его оптимизировать, в плане времени выполнения?


Ответ

Погонял алгоритм на fullHD jpeg'e. У меня на нём выходит чуть боле 2млн итераций суммарно.(внешний параллельный + внутренний) И тут, я боюсь оптимизировать особо не получится. Примерные затраты по коду:
int indx = y * WidthImage * 4 + 4 * x; -25%
float brightness = (float)(arrayPixelsImage[indx] + arrayPixelsImage[indx + 1] + arrayPixelsImage[indx + 2]) * CoeffColor; -70%
massBrightness[x, y] = brightness;-3%
сам цикл -2%
Учитывая общее кол-во итераций не лишним будет отметить, что накладные расходы на создание нового таска на каждой итерации Parallel.For практически нивелируют выигрыш от использования распараллеливания при сравнении с последовательным циклом с таким же кол-вом итераций. Т.е. цикл с 2М итераций с тем же телом выполняется почти за то же кол-во тиков.
Резюмируя свои мысли по поводу оптимизации данного кода:
На C# вряд ли удастся достичь хотя бы 2-х кратного прироста производительности. Можно оптимизировать все вычисления и операции доступа/присвоения, но максимум, чего удастся добиться это 30% прироста на "удачном" прогоне по отношению к среднему результату до оптимизации. Если учесть что винда система отнюдь не реального времени то даже оптимизированный вариант может ( и достаточно часто будет) отрабатывать дольше чем средне время для не оптимизированного варианта.
Если нужно "лопатить" большие объёмы данных и по другому никак при этом выполняя на каждом кванте (единице данных) достаточно простые/быстрые операции то я рекомендую смотреть вам в сторону использования ресурсов GPU (OpenCL или CUDA)
Для всех остальных случаев я бы смотрел в сторону упрощения алгоритма или уменьшения числа операций. Например понижал бы разрешение изображения пока это не сильно сказывается на результате. Ощутимо упростить что-либо в этих 3-х строчках кода вряд ли получится. Поэтому думайте как уменьшить число итераций.

Пропадают записи в crontab [закрыт]

В последнее время пропадают записи из кронтаба чудесным образом вообще, в первый раз когда произошло подумал что какое то серьезное обновление произошло и записи подтерлись, но это случилось и во второй раз, подскажите куда копать вообще, а то не очень хорошо на боевом сервере. Задания из под рута Linux Debian 8
Поискал в сети есть вариант что это из за того что вместо табов стоят пробелы проверяю.

обновление из «ответа»
Ответ оказался совсем простым: промахнулся, и вместо crontab -e написал crontab -r


Ответ

куда копать вообще
направления розысков (порядок — случайный)
ваша ошибка/невнимательность ошибка/невнимательность ваших коллег сторонее программное обеспечение, взятое из «левых» источников (типа «официальных сайтов» и т.п.) взлом (включает утечку/подбор паролей, эксплуатацию какой-нибудь [не]известной уязвимости какой-нибудь программы и т.д. и т.п.)

очень общие и поверхностные рекомендации:
внимательный просмотр логов, предшествующих изменению файла просмотр вывода программы last (подробнее — $ man last) проверка контрольных сумм файлов, входящих в пакеты (пакет debsums) «слежка» за изменением файлов с использованием механизма inotify (например, с помощью incron)

json_decode($string, true)

Дано:
$str = '{"1013":[{"type":6,"value":"The hormone hCG is released when you conceive, and may alter your mood."},{"type":8,"value":"Make sure you log your data to find a pattern between your symptoms, and whether or not you conceived."},{"type":7,"value":"You are approaching the end of your menstrual cycle and of the luteal phase. Progesterone will continue to be produced until the corpus luteum breaks down about 14 days after ovulation (it does not break down if an embryo implants). At this point, your uterine lining is of no use so your period will begin."}]}'; echo $str; echo "

";
Используя $json = json_decode($string, true) нужно вывести на экран данные касательно только {"type":8, "value"}. Как это правильно сделать? Пожалуйста подскажите! Особых идей нет, kак вариант:
$str = '{"1013":[{"type":6,"value":"The hormone hCG is released when you conceive, and may alter your mood."},{"type":8,"value":"Make sure you log your data to find a pattern between your symptoms, and whether or not you conceived."},{"type":7,"value":"You are approaching the end of your menstrual cycle and of the luteal phase. Progesterone will continue to be produced until the corpus luteum breaks down about 14 days after ovulation (it does not break down if an embryo implants). At this point, your uterine lining is of no use so your period will begin."}]}'; echo $str; echo "

";
$element1 = array(); $element1["type"] = 6; $element1["value"] = "The hormone hCG is released when you conceive, and may alter your mood.";
$element2 = array(); $element2["type"] = 8; $element2["value"] = "Make sure you log your data to find a pattern between your symptoms, and whether or not you conceived.";
$element3 = array(); $element3["type"] = 7; $element3["value"] = "You are approaching the end of your menstrual cycle and of the luteal phase. Progesterone will continue to be produced until the corpus luteum breaks down about 14 days after ovulation (it does not break down if an embryo implants). At this point, your uterine lining is of no use so your period will begin.";
$elements = array(); $elements[0] = $element1; $elements[1] = $element2; $elements[2] = $element3;
$final = array(); $final[1013] = $elements;
$json = json_decode($final, true); echo $json;


Ответ

$json = json_decode($string, true); // раскодировать в виде ассоциативного массива foreach($json['1013'] as $elem) { echo $elem['type'], " ", $elem['value']; }
Просто пройтись по массиву в поле '1013'
{ "1013": [{"type":6,"value":"The hormone hCG is released when you conceive, and may alter your mood."}, {"type":8,"value":"Make sure you log your data to find a pattern between your symptoms, and whether or not you conceived."}, {"type":7,"value":"You are approaching the end of your menstrual cycle and of the luteal phase. Progesterone will continue to be produced until the corpus luteum breaks down about 14 days after ovulation (it does not break down if an embryo implants). At this point, your uterine lining is of no use so your period will begin."}] }
Запись предстваляет собой объект с 1 полем '1013', в этом поле лежит массив из 3 объектов, каждый из которых состоит из поля 'type' и 'value'
json_decode($string, true); -раскодирует json, второй аргумент означает, что не в виде объекта, а в виде ассоциативного массива. Вот и получается, что мы проходим по массиву, хранящемуся в 1м поле

Как сделать мигающее окно

Делаю сейчас программу, в которой второе окно должно мигать морзянкой сменяя черный фон белым. Я уже и через таймер попробовал в самом коде окна и в отдельный поток выкладывал. Сейчас у меня такой вариант(тестовый) и он не работает. Появляется белое окно, потом проходит время равное сумме всех интервалов таймера и потом окно становится черным, хотя задумка теста - окно должно мигать несколько раз с интервалом, заданным в таймере
for(int j = 0; j < 3; j++) { this->setPalette(QPalette(Qt::white)); this->show(); m_timer->start(2000); }
коннект для приема сигнала от таймера
QObject::connect(m_timer, SIGNAL(timeout()), this, SLOT(BlackWindow()));
и сам слот
void morzewindow::BlackWindow() { this->setPalette(QPalette(Qt::black)); this->show(); m_timer->stop(); }
Может у кого-то была подобная задача реализованная средствами Qt? помогите. Мне как новичку уже ни одной идеи в голову не приходит. Все что знал, о чем подозревал, все перепробовал.
UPDATE:
запуск потока и функции в нем:
MorzeBlinkTimer.moveToThread(&MorzeBlinkThread); QObject::connect(&MorzeBlinkTimer, SIGNAL(latency(bool)), SLOT(Blink(bool))); MorzeBlinkThread.start(); MorzeBlinkTimer.startBlink(etalon2.GetReadyCodeMorzeForBlink());
функцию запускаю вручную, потому что она принимает указатель на массив с морзянкой.
//слот для смены цвета окна морзянки черный/белый
void morzewindow::Blink(bool BlackWhite) { if(BlackWhite) { this->setPalette(QPalette(Qt::white)); this->show(); } else { this->setPalette(QPalette(Qt::black)); this->show(); } }
и сама функция потока, которая вводит задержку(фрагмент):
void startBlink(int* morze) { for(int i = 0; i < 50; i++) { switch(morze[i]) { case 0: emit latency(true); QThread::msleep(iDot); emit latency(false); QThread::msleep(iPauseSymbol); break; } } }


Ответ

Все правильно, пока все функции не отработают и не "встанут" в ожидании событий в графическом интерфейсе - он не обновится.
Делать надо отдельным потоком, но там есть тонкости, тоже долго получалось как у вас - что не реагировало окно ни на что, пока не отработают все события.
Вот рабочий пример обновления графического интерфейса в отдельном потоке.
В основной функции у вас должно быть примерено так:
//Starting process in the new thread Worker * pWorker = new Worker; QThread * pThread = new QThread(); pWorker->moveToThread(pThread); connect(pThread, SIGNAL(started()), pWorker, SLOT(slotDummyUpdatingRequest())); // сигнал старта потока соединяем с функцией имеющей задержки connect(pWorker, SIGNAL(sigDummyNextRequestStage()), this, SLOT(slotStageRequestPrint())); // сигнал от объекта осуществляющего задержки на обновление окна соединяем со слотом обновления окна текущего оъекта pThread->start();
И сам слот обновления графики, срабатывающий асинхронно:
void UpdatingRequestState::slotStageRequestPrint() { //здесь идет установка внешнего вида элементов, в моем случае используется QML QObject * pList = m_pQmlObject->findChild("requestList"); m_strListView.append(tr("requesting info...")); pList->setProperty("model", m_strListView); }
Ну и собственно функция, выполняемая в отдельном потоке, по сигналам которой интерфейс обновляется
void Worker::slotDummyUpdatingRequest() { //dummy imitation of the work for (int i = 0; i < 5; i++) { QThread::msleep(500); // задержка emit sigDummyNextRequestStage(); qDebug() << "Updating Request..."; } }

Не удается раздать статику с nginx

Сконфигурировал сервер на отдачу статики, получаю "403 Forbidden"
Мой конфиг:
worker_processes 1; events { worker_connections 1024; } http{ server{ location / { root /home/danya/Desktop/data/www; } location /images/ { root /home/danya/Desktop/data; } } }
Пробовал ходить на http//localhost/index.html , http//localhost/home/danya/Desktop/data/www/index.html , http//localhost/home/danya/Desktop/data/images/1.jpg
[danya@stdfx_arch data]$ tree . ├── images │   ├── 1.jpg │   ├── 2.gif │   └── 3.png └── www └── index.html
/home/danya/Desktop/data
В чем может быть дело?Может я с расположением статики накосячил?


Ответ

пользователь, от имени которого запущен процесс nginx, не имеет доступа к файлам/каталогам, которые вы указали.
возможные варианты выхода (в порядке убывания степени разумности):
расположить файлы в более подходящем месте (часто — в /var/www/) и сделать их владельцем пользователя, от имени которого запущен процесс nginx запускать процесс nginx от имени того пользователя/группы, который имеет доступ (хотя бы на чтение) к нужным вам файлам/каталогам. изменить права доступа к нужным вам файлам/каталогам так, чтобы пользователь, от имени которого работает nginx, имел к ним доступ хотя бы на чтение.

Как получить цвет div блока на js?

Как можно получить цвет div блока (background css) и вывести например через alert()? Например: чтобы выводилось ff7659 после клика на кнопку.
Код на : jsfiddle.net
Html:



Получить цвет

Js:
$("#but_color").click(function () {
//alert();
});
Css:
#color_bk{ height:150px; width:150px; background: #ff7659; }
#but_color{ height:20px; width:150px; background: #5ca7df; padding: 5px 0; text-align: center; color: #000; font-size:16px; font-weight:bold; cursor: pointer; }


Ответ

$("#but_color").on('click', function () { var bg = $("#color_bk").css("backgroundColor"); alert(parseColor(bg).hex); });

function parseColor(color) { var arr=[]; color.replace(/[\d+\.]+/g, function(v) { arr.push(parseFloat(v)); }); return { hex: "#" + arr.slice(0, 3).map(toHex).join(""), opacity: arr.length == 4 ? arr[3] : 1 }; } function toHex(int) { var hex = int.toString(16); return hex.length == 1 ? "0" + hex : hex; }

parseColor("rgb(210, 10, 10)"); // {"hex":"#d20a0a","opacity":1} parseColor("rgba(210, 10, 10, 0.5)"); // {"hex":"#d20a0a","opacity":"0.5"} parseColor("rgb(210)"); // {"hex":"#d2","opacity":1}

Разделить двумерный массив на два вектора

Имеется таблица в виде массива, где по первому индексу my_array[i][0] получаем id, my_array[i][1] по второму наименование. Нужно разделить его на два отдельных массива: один с именами, другой с id. Решение, которое пришло в голову:
id = [] names = [] for item in my_array: id.append(item[0]) names.append(item[1])
Возможно ли реализовать это проще, без цикла по всему массиву?


Ответ

Если я правильно понял задачу, то например так:
id, names = list(zip(*my_array))[:2]
P.S.: Если вас интересует производительность, то стоит обратить внимание на numpy и т.п.

Возвращаемая строка содержит нечитаемые символы

Использую psycopg2 для работы с Postgress БД. Получаю вот такое вот строковое значение при запросе к БД: " insider’s guide to a woman’s ". Должно быть insider's guide to a woman's. Помогите найти решение


Ответ

insider’s guide это так называемые кракозябы (даже президенты от этого не застрахованы), которые получаются когда текст, закодированный в одной кодировке показан в другой несовместимой кодировке:
>>> print(u"insider’s guide to a woman’".encode('cp1251').decode('utf-8')) insider’s guide to a woman’
В вашем случае utf-8 текст показывался, используя cp1251 кодировку.
Чтобы уменьшить вероятность подобных ошибок, храните текст как Юникод, а не байты: преобразуйте на входе байты в Юникод, используйте Юникод внутри программы, кодируйте в байты на выходе (если необходимо) ☯:
unicode_text = bytestring.decode(character_encoding) bytestring = unicode_text.encode(character_encoding)

Адаптивное позиционирование элементов в круг

Мне нужно, чтобы одинаковые элементы html выстроились в круг(в центре еще один элемент) При этом также нужно учесть то, чтобы при различных разрешениях экрана они не превращались в эллипс, а всегда оставались кругом. Осложняется эта задача тем, что обязательна аналогичная адаптивность на мобильных устройствах.

Выберите интересующую тему
Что-то

И css
.circle { width: 10%; background: #900C3F; border-radius: 50%; text-align: center; font-size: 18px; margin: 0 auto; cursor: pointer; transition: 1s ease-in; overflow: hidden; position: absolute; } .circle:hover { background: #0C905D; } .circle__main { width: 20%; position: static; } .circle__inv { width: 100%; height: 100%; padding-top: 50%; } .circle__text { transform: translateY(-50%); display: inline-block; }


Ответ

Условимся, что в css адаптивный круг и адаптивный квадрат одно и тоже, т.к. border-radius это лишь псевдо круг.
Решение:
1 Для решения нам понадобится два родительских контейнера(для задания адаптивного квадрата, см. 2) и контейнеры-круги.
2. Адаптивный квадрат создается с помощью padding-(top|bottom): 100%;. Процент в данном случаи берется от ширины родительского контейнера (такая вот особенность).
.parent { width: 100px; } .child { height: 0; padding-bottom: 100%; // размер .child будет 100px на 100px }
3. Центральный круг можно позиционировать многими способами, я предпочитаю через absolute
.circle_main { position: absolute; top: 0; right: 0; bottom: 0; left: 0; margin: auto; //фокус именно в margin: auto; width: 30%; //к примеру height: 30%; //к примеру }
4. Для честного позиционирования, придется использовать js, что бы правильно рассчитать координаты внут. кругов.
Пример решения (с комментариями)
Советую изменить расположение так, что бы круг был слева или справа (удобнее изменять ширину окна) Кол-во кругов можно изменять на произвольное кол-во (см. блок html) Всё сделано в процентах, так что полная адаптивность Самое главное это выбрать размер внут. круга. В примере используются препроцессор(stylus) и шаблонизатор(jade), если с ними не знакомы, то там есть кнопка View Compiled. Тоже самое с js Адаптивный текст реализован с помощью едениц изменерия vw, не везде работает, тут лучше протестировать или найти другой способ изменять размер текста (не стал тут заморачиваться особо).

smtplib в Python c smtp.yandex.ru

Юзаю Python 3.4.3. Хочу написать простенький скрипт, который будет отсылать на заданный ящик текстовую информацию. Нашёл : следующий пример. В режиме интерпретатора ввожу:
>>> import smtplib >>> server = smtplib.SMTP('smtp.yandex.ru', 465)
И на второй строчке интерпретатор наглухо виснет. Для Яндекса инфу о сервере брал отсюда
UPD: если использовать то же для Gmail:
server = smtplib.SMTP('smtp.gmail.com', 587)
То всё норм. Однако хочется (т.е. имеется ящик) подключаться к Яндексу. Возможно это?
UPD2: если для Яндекса юзать порт 587, то вторая строчка тоже проходит. Однако третья:
server.login("youremailusername", "password")
Приводит к поднятию эксепшена smtplib.SMTPServerDisconnected
UDP3: нашёл этот вопрос. Делаю так:
import smtplib smtp = smtplib.SMTP_SSL() smtp.connect('smtp.yandex.ru')
И вываливается ssl.SSLEOFError
UPD4: Нашёл эту ссылку и сделал так:
server = smtplib.SMTP_SSL('smtp.yandex.ru:465') server.login('login', 'pass')
И всё заработало. Заработало в том смысле, что пришло smtplib.SMTPAuthenticationError с сообщением, суть которого заключается в том что я веду себя как робот и мне надо привязать номер мобильного чтобы система перестала видеть во мне робота. Видимо, защита от подбора пароля.


Ответ

@Xyanight (надеюсь я его позвал): для Gmail
import smtplib
def sendEMail(text): server = smtplib.SMTP("smtp.gmail.com", 587) server.ehlo() server.starttls() server.login("login", "pass") message = "
".join([ "From: от кого", "To: кому", "Subject: тема", "", str(text) ]) server.sendmail("от кого", "кому", message) server.quit()

Фиксация меню, когда оно доходит к верху, и отключение фиксации по завершению секции

Подскажите как сделать, чтобы горизонтальное меню в определенной секции (в середине лендинга), когда доходит к верху страницы стало фиксированное,(прилипало к верху), причем все остальное содержимое проходило под ним; а после окончания секции, в котором находится меню, отключалась фиксация и меню прокручивалось дальше...


Ответ

поставить две "метки": в начале секции и в конце cоздать событие на скролл, которое бы вычисляло положение страницы и включало или отключало фиксацию.
Предлагаю такой вариант:
function stickMenu() { var windowTop = $(window).scrollTop(); var sectionStarts = $('#sectionStarts').offset().top; var sectionEnds = $('#sectionEnds').offset().top; if (windowTop > sectionEnds) { $('.menu').removeClass('fixed'); } else if (windowTop > sectionStarts) { $('.menu').addClass('fixed'); } else { $('.menu').removeClass('fixed'); } } $(window).scroll(function() { stickMenu(); }); div:not(.menu) { height: 300px; } .menu { background-color: lightgray; } .menu.fixed { position: fixed; top: 0; }

Начало страницы
Начало секции
Содержимое секции
конец секции
Конец страницы

Custom fonts in widget

Здесь написано, что чтобы использовать свои шрифты нужно их превращать в картинку с помощью битмапа и вставлять в виджет эту картинку. Вопрос 5-и летней давности, неужели эта проблема так и не решена? Английские шрифты в Android Studio приятные, а вот кириллические шрифты явно не доработаны. Есть ли какой-то способ без костылей свои шрифты внедрить?


Ответ

Есть способ, выдолжны добавить свои шрифты в папку assets в папке приложения (где хранится папка java и папка ресурсов), если её нету, то создайте в том месте где описано выше. Пример исползования:
textView.setTypeface(Typeface.createFromAsset(getAssets(), "tahoma.ttf"));

Получение данных из “такой” карты высот

от есть такой кусок карты высот (8бит на канал)

Как я догадался, эти резкие скачки отвечают за разные уровни высоты. То есть, где где большая разница между светлым и голубым, там осуществляется переход между уровнями. При этом участки светлее отвечают за меньшую высоту на своем уровне.
Значит попробовал я следующим образом: на каждой строке проверять разницу между значениями красного канала на соседних пикселях. Взять к примеру константу max_dist = 180, и если разница больше max_dist , тогда засчитывать переход на следующий уровень, то же самое с переходом на предыдущий уровень при разнице меньше -max_dist.
Но это не работает, только появляются полосы. Какие еще есть способы извлечь такие данные?
UPDATE: Оказалось все еще интереснее)
Склеив все эти кусочки получил


Ответ

Зеленый канал определяет абсолютную высоту, хотя поделен на несколько уровней(их нужно разделять, в данном примере первый уровень в голубых областях, второй в последующей красной с зеленым области, и последний в правом нижнем углу.
Красный канал это остаток зеленого.По возвышениям 255 единиц из красного немного меньше чем 1 единица из зеленого. Отсюда можно вывести формулу
Синий канал содержит только пару уровней возвышения зеленого (но их оказывается больше, поэтому он бесполезен, все равно нужно вручную отделять уровни)
elevation = level*255 + green + red/256

Удалить элементы из вектора в MATLAB

Пытаюсь удалять элементы из вектора в Matlab по какому-либо условию. Например хочу удалить все четные числа.
a = [1 2 3 4 5 6]; for i = 1:numel(a) if (mod(a(i), 2)) == 0 a(i) = []; end end
При этом получаю "Index exceeds matrix dimensions.". Похоже цикл продолжает крутиться до первоначальной длины вектора, не смотря на то, что она уменьшилась. Как с этим бороться?
Но если быть до конца точным, я хочу написать такой цикл:
function [centers, rads, metrics] = ... DeleteOverlapCircles(centers, rads, metrics)
for i = 1:(length(metrics) - 1) for j = (i + 1):length(metrics) minRad = min([rads(i), rads(j)]); maxRad = max([rads(i), rads(j)]); if pdist2(centers(i), centers(j)) < maxRad + 1 / 2 * minRad metrics(j) = []; centers(j) = []; rads(j) = []; end end end end
Вопрос решился следующим образом:
function [centers, rads, metrics] = ... DeleteOverlapCircles(centers, rads, metrics)
for i = (length(metrics) - 1):-1:1 for j = (i - 1):-1:1 minRad = min([rads(i), rads(j)]); maxRad = max([rads(i), rads(j)]); if pdist2(centers(i, :), centers(j, :)) ... < maxRad + 1 / 2 * minRad
centers(i, :) = []; rads(i) = []; metrics(i, :) = []; break; end end end end
Но я не готов поверить, что нет более очевидного и красивого решения.


Ответ

Цикл for не предназначен для условий, которые изменяются внутри цикла. То есть, при наличии условия
for i = 1:numel(a)
значение numel(a) будет вычислено только однажды, при входе в цикл.
Если же конечное значение будет менятся, нужен цикл while:
a = [1 2 3 4 4 5 6]; i = 1; while i <= numel(a) if (mod(a(i), 2)) == 0 a(i) = []; else i = i+1; end end
Замечу, что переменная цикла не увеличивается в случае удаления элемента, поскольку при этом другие элементы сдвигаются.
(Но перебирать с конца в начало, как Вы сделали, на самом деле проще.)

Преобразовывание спец. символов XML

Есть текст, в котором есть <,> и т п ESCAPE символы XML.
Подскажите, есть ли стандартные способы преобразования этого в человеческий текст?
(Где вместо ESCAPE символов используются нормальные символы)
Или можно исправить проблему банальным, последовательным REPLACE?


Ответ

Как вариант:
string encoded = "(A > B) & (C < D)";
XmlDocument doc = new XmlDocument(); string xml = string.Format("{0}", encoded); doc.LoadXml(xml); string decoded = doc.DocumentElement.InnerText; //(A > B) & (C < D)
или
string encoded = "(A > B) & (C < D)";
using (var sr = new StringReader(string.Format("{0}", encoded))) using (var xr = XmlReader.Create(sr)) { xr.MoveToContent(); string decoded = xr.ReadElementContentAsString(); //(A > B) & (C < D) }

Откуда поисковые системы узнают о новых сайтах?

Кто-нибудь знает откуда поисковые системы узнают о новых сайтах (доменах)? Если, к примеру, никто не сообщал о сайте в панели вебмастера поисковой системы и не ссылался на этот сайт. Хотя он через какое-то время появляется в индексе.


Ответ

Данные из браузеров. Когда разработчик делает свой сайт, он часто на него заходит. Браузер все это собирает. Google Chrome - Google. Internet Explorer, Edge - bing. Yandex.Browser - Yandex. Некоторые поисковики пользуются базами Google и Yandex. Регистраторы доменов. У них на сайте есть ссылки. Потом еще возможно когда человек регистрирует домен, ему на почту регистратор отправляет письмо со счетом о покупке. Компании проверяют эти письма, спам или не спам. И т.д. А в письмах есть ссылки, робот на них переходит и проверяет. Потом еще у меня такое было, что кидаю ссылку в вк кому то из друзей и вижу что робот ООО "Вконтакте" заходил на сайт. Не исключено что так и с письмами на почту.

Доступ ненадежным приложениям при отправке почты с помощью Gmail

СОбственно говоря,есть задача отправлять письма с помощью java. Покопавшись в сети, прописал такой код:
public class MailSender {
private final String username = "адрес ящика, с которого отправляем письмо"; private final String password = "пароль к почтовому ящику";
public void MailSending(Message DataMessage){
Properties props = new Properties(); props.put("mail.smtp.starttls.enable", "true"); props.put("mail.smtp.auth", "true"); props.put("mail.smtp.host", "smtp.gmail.com"); props.put("mail.smtp.port", "587"); props.put("mail.smtp.ssl.trust", "smtp.gmail.com");
Session session = Session.getInstance(props, new javax.mail.Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(username, password); } });
try { MimeMessage message = new MimeMessage(session); message.setFrom(new InternetAddress(DataMessage.getFrom())); message.addRecipient(MimeMessage.RecipientType.TO, new InternetAddress(DataMessage.getTo())); message.setSubject(DataMessage.getSubject()); message.setText(DataMessage.getBody());
Transport.send(message); System.out.println("Email Sent successfully...."); } catch (MessagingException mex){ mex.printStackTrace(); }
}
Это дело работает и письма шлет,НО только в том случае, если я в настройках ящика включаю "доступ к ненадежным приложениям"(в противном случае кидает в меня javax.mail.AuthenticationFailedException). Я так думаю,что это делать не желательно(безопасность и все такое), в тоже время решений как обойти эту процедуру я не нашел. Можно ли изменить код так,чтобы проходила аутентификация,доступ ненадежным приложениям был отключен и он не ругался?


Ответ

Сначала включите двухэтапную аутентификацию После этого получите пароль для приложения и используйте его для отправки писем.
Также стоит рассмотреть возможность отправки писем через свой сервер.

Как реализовать перетягивание элементов в ExpandableListView?

Есть ExpandableListView, в нем несколько элементов верхнего уровня, и в них десяток вложенных элементов списка!
Проблема состоит в том, что нужно реализовать возможность, перетаскивание вложенных элементов, как в области одной группы, так и в другие группы !
Возможно стандартного решения этой задачи нет ? Как поступить в данной ситуации ?
Как можно это сделать ? Что нужно использовать ?


Ответ

Есть несколько библиотек, позволяющих это сделать (перечислены явно не все):
Drag and Drop Expandable ListView, предложенная Андроид Андроидом в комментарии DragListView. На демо нет ExpandableListView, но обратите внимание на BoardView, возможно, Вам понравится такая реализация. Advanced RecyclerView, основанный на более кастомизируемом RecyclerView вместо ExpandableListView. Здесь как раз пример использования drag-and-drop с группированым списком.
Если использование сторонних библиотек по какой-то причине невозможно, то вот тут можно найти пример самостоятельной реализации drag-and-drop, правда для обычного ListView
В общем случае, я бы советовал воспользоваться Advanced RecyclerView из-за развёрнутой документации и возможностей по кастомизации. Если Вам необходимо максимально простое решение, то, вероятно, Drag and Drop Expandable ListView будет лучшим вариантом.

Как убрать видимость ободка у внешнего border-radius?

Заметил такую неприятную особенность у border-radius, когда при наложении фона вложенного элемента (в данном случае li) на внешний (ul) виден неприятный ободок. фидл
ul { background-color: #000; display: inline-block; height: 50px; line-height: 50px; padding: 0; border-radius: 4px 0 0 4px; } li { display: inline-block; list-style: none; } li.active { background-color: yellow; border-radius: 4px 0 0 4px; } a { text-decoration: none; }



Ответ

Вариант другой - псевдоэлементы. Но, если у вас глаз настолько алмаз, что различия ширины в 1px - это слишком, то он не для вас. Суть - у li.active нет border-radius, к первому и последнему элементу меню присваиваем дополнительный класс, который обеспечивает их соответствующими псевдоэлементами с абсолютным позиционированием. Сдвиаем их(псевдоэлементы) на 1px, скрывая все, что нужно скрыть. Профит, вы великолепны. http://codepen.io/malginovdesign/pen/KzXWQN?editors=1100
/* оформление */ * { box-sizing: border-box; } div { background: darkgrey; padding: 0 20px; width: 800px; margin: 0 auto; border-radius:4px; } a { text-decoration:none; color: #f9f9f9; } /* объект */ ul { display:inline-block; height:50px; line-height:50px; padding: 0; border-radius:4px; width: 100%; background: #333; } li { display:inline-block; list-style:none; width: calc(100% / 5); text-align:center; position: relative; } .active.first-link:before { content: ''; position: absolute; top: 0; left: -1px; height: 100%; width: 5px; background: darkorange; border-radius: 4px 0 0 4px; } .active.last-link:after { content: ''; position: absolute; top: 0; right: -2px; height: 100%; width: 5px; background: darkorange; border-radius: 0 4px 4px 0; } .active { background-color: darkorange; }


VK SDK Серверные методы API как вызывать?

Добрый вечер) Пишу небольшое приложение с использованием VK SDK. Необходимы серверные методы API secure.* (например secure.sendNotification). Для их вызова нужно получать другой token с помощью специальной схемы, которая плохо описана в документации.
'https://oauth.vk.com/access_token?client_id=' + CLIENT_ID + '&client_secret=' + CLIENT_SECRET + '&v=5.50&grant_type=client_credentials'
где я вставляю свой client_id и client_secret. Только не знаю, как вызвать этот запрос и получить обратно токен, чтобы его использовать в методах secure.* .
Может быть кто-то знает, как это сделать? Можно пример и на java и на C#.


Ответ

Вот рабочий пример на Java с помощью либы OkHttp
Thread thread = new Thread() { @Override public void run() { try { OkHttpClient client = new OkHttpClient.Builder().build();
Request.Builder request = new Request.Builder();
String CLIENT_ID = "Цифры тут из настроек приложения в ВК"; String CLIENT_SECRET = "Секретный код из настроек приложения в ВК"; request.url("https://oauth.vk.com/access_token?client_id=" + CLIENT_ID + "&client_secret=" + CLIENT_SECRET + "&v=5.50&grant_type=client_credentials");
Response response = client.newCall(request.build()).execute();
String answer = response.body().string(); Log.e("LOG", answer); } catch (IOException e) { e.printStackTrace(); } } };
thread.start();
Выведет это:
{"access_token":"sdfsdfsdfsdfsdf8sdfsdfsdfsdfsdfsdfsdf","expires_in":0}
Так что вам надо лишь прочитать ответ ВК на ваш запрос. Вот тут есть ещё примеры Java кода по вытаскиванию инфы из ответа, получаемого по URL: тык
Собственно, эту же строку-ответ ВК вы можете увидеть и просто вбив получившийся адрес в браузер.

Узнать количество элементов в sql с помощью cursor

В Android приложении имеется SQL-бд.
Задача - получить рандомную запись с помощью класса Random.
Алгоритм:
Делаем необходимый запрос к бд Получаем количество записей после запроса Генерируем случайное число Перемещаемся на случайную запись Забираем ее
if(countQuestion!=0){
Cursor cursor = db.query(EgeDBHelper.QUESTIONS_TABLE, new String[]{EgeDBHelper.COLUMN_ID, EgeDBHelper.LESSON_ID, EgeDBHelper.QUESTION_TYPE, EgeDBHelper.QUESTION}, EgeDBHelper.LESSON_ID+"='"+id.toString()+"' AND "+EgeDBHelper.QUESTION_TYPE+"='"+(i+1)+"'", null, null, null, null);//Запрос
for(int j = 0; j < countQuestion; j++){ int a = random.nextInt(cursor.getCount()); cursor.move(a); Log.d("Random", String.valueOf(a)+" "+String.valueOf(cursor.getCount())); int questionID = cursor.getInt(cursor.getColumnIndex(EgeDBHelper.COLUMN_ID)); questions.add(new Question(questionID, db)); } cursor.close(); }
}
Компилятор выдает:
android.database.CursorIndexOutOfBoundsException: Index 42 requested, with a size of 42
Логи:
D/Random: 30 42 D/Random: 27 42 D/AndroidRuntime: Shutting down VM


Ответ

Вы используете не тот метод для установки курсора на позицию.
Метод move перемещает курсор на переданное в виде аргумента число позиций от текущего положения, а не устанавливает на указанную позицию.
Вам нужен метод moveToPosition

Масштабирование SVG карты страны относительно выбранного округа

Есть SVG карта страны. Нужно достичь эффекта, чтобы при клике на округе происходило бы масштабирование относительно центра выбранного округа, т.е. transfrom-origin должен находится в центре выбранного округа. Хотелось бы обойтись без каких-либо библиотек
Первый вопрос это почему здесь, когда задано значение viewBox, то polygon'ы построенные по точкам, полученным от getBoundingClientRect(), не совпадают с самими элементами svg, map и e.target? Если добавлять коэффициенты, как тут, то какие тогда должны быть значения у viewBoxMapCoefX1 и viewBoxMapCoefX1, чтобы полученный mapPolygon совпадал с map? Если масштабировать map с помощью:
// ANIMATION HERE map.style.transformOrigin = transformOriginX + "px " + transformOriginY + "px"; map.style.transform = "scale(" + scale + ")";
то выглядит так, как будто значение transformOrigin неверное. Если попытаться изменить viewBox
// ANIMATION HERE svg.viewBox.baseVal.x = bounding.left; svg.viewBox.baseVal.y = bounding.top; svg.viewBox.baseVal.width = bounding.width; svg.viewBox.baseVal.height = bounding.height;
то как тогда можно сделать плавную анимацию масштабирования только средствами CSS (без SMIL)?
Буду благодарен любой помощи и советам по делу.


Ответ

1) Нужно использовать .getBBox() вместо getBoundingClientRect(), чтобы получить координаты относительно самого SVG, а не экрана. Результат
3) Вместо масштабирования карты относительно центра выбранного субъекта (transformOrigin + scale) можно центр субъекта получить в % вместо px и переместить в центр карты, а потом сделать масштабирование, т.е.:
// ANIMATION HERE var transformOriginXPercent = (50 - transformOriginX * 100 / mapBounding.width) * scale; var transformOriginYPercent = (50 - transformOriginY * 100 / mapBounding.height) * scale; var scaleText = "scale(" + scale + ")"; var translateText = "translate(" + transformOriginXPercent + "%," + transformOriginYPercent + "%)";
map.style.transformOrigin = "50% 50%"; map.style.transform = translateText + " " + scaleText;
и тем самым достичь нужного результата
В целом вопрос решен, однако интересно, как можно достичь этого же эффекта с помощью:
map.style.transformOrigin = (transformOriginX) + "px " + (transformOriginY) + "px"; map.style.transform = "scale(" + scale + ")";
подобрав правильные коэффициенты для transformOriginX и transformOriginY

Проблема в OpenGL с неверными координатами вывода изображения

Всем привет! Возникла проблема с glViewport в OpenGL ES 2.0 под Android. Я реализовал следующий алгоритм. Изображение генерируется в текстуру с использованием FBO. Шейдер, который генерирует изображение, также принимает на вход предыдущую отрисованную текстуру того же размера. Шейдер использует ее для более быстрой генерации следующей текстуры. Для всего этого у меня есть 2 фреймбуфера (+ экранный фреймбуфер), к каждому из которых приаттачена 1 текстура. После каждого цикла отрисовки ссылки на фреймбуферы меняются местами, чтобы каждый раз не копировать предыдущее изображение. Размер текстуры степени 2, т.е. размеры текстуры и экрана не совпадают.
Итак, проблема в том, что на экран рендерится не вся текстура, а лишь ее часть.
Код отрисовки:
//Меняем местами ссылки на буферы evenRender = !evenRender; int srcFB = evenRender? 0:1; int dstFB = evenRender? 1:0;
//Привязываем буфер, куда будет генерироваться изображение GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, frameBufferID[dstFB]); //Выбираем размеры окна вывода как размеры экрана устройства **GLES20.glViewport(0, 0, mScreenWidth, mScreenHeight);** GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
//Выбираем предыдущую отрисованную текстуру GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + srcFB); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, frameTextureID[srcFB]);
//Устанавливаем шейдер для генерации изображения GLES20.glUseProgram(sp_ImageGeneration);
int mPositionHandle = GLES20.glGetAttribLocation(sp_ImageGeneration, "vPosition"); GLES20.glVertexAttribPointer(mPositionHandle, 3, GLES20.GL_FLOAT, false, 0, offscreen_vertexBuffer); GLES20.glEnableVertexAttribArray(mPositionHandle);
int mTexCoordLoc = GLES20.glGetAttribLocation(sp_ImageGeneration, "a_texCoord"); GLES20.glVertexAttribPointer ( mTexCoordLoc, 2, GLES20.GL_FLOAT, false, 0, offscreen_uvBuffer); GLES20.glEnableVertexAttribArray(mTexCoordLoc);
...
//Отправляем шейдеру предыдущую отрисованную текстуру int mSamplerLoc = GLES20.glGetUniformLocation (sp_ImageGeneration, "prev_frame" ); GLES20.glUniform1i(mSamplerLoc, srcFB);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, indices.length, GLES20.GL_UNSIGNED_SHORT, drawListBuffer);
GLES20.glDisableVertexAttribArray(mPositionHandle); GLES20.glDisableVertexAttribArray(mTexCoordLoc);
//Привязываем экранный буфер GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); GLES20.glViewport(0, 0, mScreenWidth, mScreenHeight); GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
//Выбираем текстуру в том буфере, куда генерировалось изображение GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + dstFB); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, frameTextureID[dstFB]);
// Устанавливаем простой шейдер GLES20.glUseProgram(sp_Image);
mPositionHandle = GLES20.glGetAttribLocation(sp_Image, "vPosition"); GLES20.glVertexAttribPointer(mPositionHandle, 3, GLES20.GL_FLOAT, false, 0, vertexBuffer); GLES20.glEnableVertexAttribArray(mPositionHandle); mTexCoordLoc = GLES20.glGetAttribLocation(sp_Image, "a_texCoord" ); GLES20.glVertexAttribPointer ( mTexCoordLoc, 2, GLES20.GL_FLOAT, false, 0, uvBuffer); GLES20.glEnableVertexAttribArray(mTexCoordLoc);
...
//Отправляем шейдеру текстуру, куда генерировалось изображение mSamplerLoc = GLES20.glGetUniformLocation (sp_Image, "s_texture" ); GLES20.glUniform1i(mSamplerLoc, dstFB);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, indices.length, GLES20.GL_UNSIGNED_SHORT, drawListBuffer);
GLES20.glDisableVertexAttribArray(mPositionHandle); GLES20.glDisableVertexAttribArray(mTexCoordLoc); GLES20.glUseProgram(0);
GLES20.glActiveTexture(0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
Координаты треугольников, на которые происходит отрисовка:
float koefWidth = (float)texSize / mScreenWidth; float koefHeight = (float)texSize / mScreenHeight;
vertices = new float[] { 0, 0, 0f, 0, mScreenHeight * koefHeight, 0f, mScreenWidth * koefWidth, mScreenHeight * koefHeight, 0f, mScreenWidth * koefWidth, 0, 0f };
offscreen_vertices = new float[] { 0, 0, 0f, 0, mScreenHeight * koefHeight* koefHeight, 0f, mScreenWidth * koefWidth * koefWidth , mScreenHeight * koefHeight* koefHeight, 0f, mScreenWidth * koefWidth * koefWidth, 0, 0f };
texSize - размер текстуры. Например, mScreenWidth = 800, mScreenHeight = 600, texSize = 1024.
Координаты текстур uvs и offscreen_uvs одинаковы:
uvs = new float[] { 0, 0, 0, 1, 1, 1, 1, 0, };
Фреймбуферы и текстуры для них были созданы так:
frameBufferID = new int[2]; frameTextureID = new int[2];
GLES20.glGenFramebuffers(2, frameBufferID, 0); GLES20.glGenTextures(2, frameTextureID, 0); GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, frameBufferID[0]); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, frameTextureID[0]);
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGB, texSize, texSize, 0, GLES20.GL_RGB, GLES20.GL_UNSIGNED_BYTE, null); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, frameTextureID[0], 0);
//Next framebuffer GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, frameBufferID[1]); GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + 1); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, frameTextureID[1]); GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGB, texSize, texSize, 0, GLES20.GL_RGB, GLES20.GL_UNSIGNED_BYTE, null); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, frameTextureID[1], 0);
Я очень долго пробовал менять значения в glViewport, выделенном звездочками, а также координаты треугольников. Но тогда либо возникали графические артефакты, либо сильно падала производительность. Заранее спасибо!


Ответ

Вопрос решен. Оказалось, "графические артефакты" были связаны со спецификой работы моего шейдера. Он берет текстуры из фреймбуфера, но я не учитывал то, что эти текстуры были уменьшены glViewport'ом. Из-за этого данные текстур обрабатывались неправильно, что и выливалось в артефакты результирующего изображения. Решилось добавлением в шейдер соответствующих коэффициентов при обработке текстур. Эта проблема мучила меня на протяжении недели, и теперь я очень рад! :)

создание удаленного сервера и подключение к нему через сокеты на java

нашел вариант реализации клиент-серверного взаимодействия посредством UDP на java. Сервер:
import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket;
public class Server { public static void main(String args[]) { try { //Создаем сокет DatagramSocket sock = new DatagramSocket(7000);
//буфер для получения входящих данных byte[] buffer = new byte[65536]; DatagramPacket incoming = new DatagramPacket(buffer, buffer.length);
System.out.println("Ожидаем данные...");
while(true) { //Получаем данные sock.receive(incoming); byte[] data = incoming.getData(); String s = new String(data, 0, incoming.getLength());
System.out.println("Сервер получил: " + s);
//Отправляем данные клиенту DatagramPacket dp = new DatagramPacket(s.getBytes() , s.getBytes().length , incoming.getAddress() , incoming.getPort()); sock.send(dp); } }
catch(IOException e) { System.err.println("IOException " + e); } } }
Клиент:
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress;
public class Example2 { public static void main(String args[]) { DatagramSocket sock = null;
BufferedReader cin = new BufferedReader(new InputStreamReader(System.in));
try { sock = new DatagramSocket();
while(true) { //Ожидаем ввод сообщения серверу System.out.println("Введите сообщение серверу: "); String s = (String)cin.readLine(); byte[] b = s.getBytes();
//Отправляем сообщение DatagramPacket dp = new DatagramPacket(b , b.length , InetAddress.getByName("localhost") , 7000); sock.send(dp);
//буфер для получения входящих данных byte[] buffer = new byte[65536]; DatagramPacket reply = new DatagramPacket(buffer, buffer.length);
//Получаем данные sock.receive(reply); byte[] data = reply.getData(); s = new String(data, 0, reply.getLength());
System.out.println("Сервер: " + reply.getAddress().getHostAddress() + ", порт: " + reply.getPort() + ", получил: " + s); } }catch(IOException e) { System.err.println("IOException " + e); } }
}
Проблема в том,что здесь взаимодействие идет через localhost и работает в рамках одного устройства...я уже несколько дней потратил на то,чтобы понять что туда передать вместо localhost,чтобы можно было запустить сервер на одном устройстве,А клиент на абсолютно другом,подключенному к другой сети,пробовал и local ip пихать и ip, который выдавали различные сайты...все не работает...подскажите пожалуйста UPD:покопавшись,я наткнулся на такую вещь как NAT и то,что я не подключаюсь напрямую к интернету,так что собственно как можно это обойти?


Ответ

решил данный вопрос и решил поделиться,мало ли кого-то на что-то натолкнет... как сказал @Victor мой ip из вне был недоступен,так роутер предоставлял единый внешний ip для всех подключенных устройств,а мой ip был внутренним,не буду особо расписывать данный момент,т.к. могу что-то сказать не правильно(просто загуглите NAT). решил проблему подключением к интернету не через роутер,а напрямую воткнув кабель в ноутбук,таким образом я напрямую(!) подключился к интернету и ip моего ноутбука стал доступен из вне,что и позволило подключиться к моему серверу человеку из другого города=) свой ip можно узнать вбив ipconfig в командную строку(для Windows, для Unix не знаю) или проверив его на одном из множества сайтов. Если они совпадают,значит вы напрямую подключены к интернету и можно смело указывать данный ip вместо localhost. Если что-то написано не правильно-дополните в комментариях.

CURL выводит ответ но не возвращает его в переменную

Ниже код:
$url = "http://site.ru/my_exchange_2.php?type=sale&mode=checkauth"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL,$url); // set url to post to curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); curl_setopt($ch, CURLOPT_USERPWD, "user:password"); $result = curl_exec($ch); curl_close($ch); echo $result;
Код выполняется, выдает ответ:
success PHPSESSID aooom9tmurdnrdukfgkk631421 sessid=e519c36f6765ec9f8eaf30ecd10d9f4d
Но в переменной $result нет ответа, а только bool(true) если смотреть через var_dump
Как получить то, что выводит curl на экран? Меня интересует sessid


Ответ

Добавьте эту опцию:
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

В Google Chrome не отображаются видео-ролики в YouTube. как исправить?

Перестали отображаться видео-ролики в YouTube. Симптомы:
Не воспроизводится и искажен звук. Не воспроизводится и искажено видео.
в ютубе видны кадры-картинки при протягивании ползунка, видео не отображается - Информацию о версии Flash:
Google Chrome 50.0.2661.94 () ОС Linux Flash plugin 21.0.0.216 /home/rapt/.config/googlechrome/PepperFlash/21.0.0.216/libpepflashplayer.so --- Crash data crash id 4d7c3b8852511a6d пятница, 4 сентября 2015 г., 8:33:17 --- GPU information --- --- GPU driver, more information --- Vendor Id 0x1002 Device Id 0x1309 Driver vendor Mesa Driver version 10.3.2 Driver date Pixel shader version 1.30 Vertex shader version 1.30
Информацию о ОС : Linux Ubuntu 14.04 Воспроизводится ли проблема в других браузерах? в других браузерах все нормально работает. Воспроизводится ли проблема в режиме Инкогнито (Ctrl+Shift+N)? в режиме Инкогнито все так же само.


Ответ

Начните со сброса настроек: скопируйте в адресную строку
chrome://settings/resetProfileSettings
и нажмите Enter и ОК
=========================
Потом скопируйте строку
chrome://flags/
и нажмите Enter Сверху справа будет кнопка Восстановить настройки по умолчанию Полный ответ здесь

Локализация WPF-приложения

Подскажите, пожалуйста, как выполнить локализацию WPF-приложения? Ни разу до этого не приходилось писать многоязыковые приложения. Локализацию строк интерфейса сделал по этой статье Локализация WPF приложений на лету. Но еще необходимо сделать перевод строк, которые выдает приложение в случае ошибки или как подсказка пользователю. Например, пользователь выбирает файл неправильного формата и получает сообщение в зависимости от выбранного языка.


Ответ

Нормальная локализация в C# представлена одним единственным способом - resx файлы.
Для небольших проектов можно просто включить ресурсы, открываем свойства проекта и пользуемся:

В проекте при этом создается resx файл с локализацией по умолчанию. Чтобы добавить ещё одну - достаточно создать (Add -> New Item -> resx) ещё один файл, дополнив имя культурой (Resources.{culture}.resx)

В коде просто пишем обращение к ресурсу:
Console.WriteLine(Resources.Example);
Для смены языка приложения принудительно достаточно поменять CurrentUICulture
Теперь по поводу дополнительных сборок. Хороших решений тут нет, простота выше описанного решения теряется, как только вы пытаетесь сделать шаг влево\вправо. Более менее рабочее решение описано тут (enSO), но оно жутко неудобное в использовании. Как можно заметить, простота использования вида Console.WriteLine(Resources.Example); теряется и обращения происходят уже вручную. Это можно автоматизировать, но тогда уже лучше вместо стандартного генератора посмотреть в сторону шаблонов (для общего представления можно глянуть MSDN).
Т.е. чтобы сделать всё в одной сборке вам придётся написать замену стандартной схеме сборки ресурсов. Стоит ли оно того - решайте сами. Если интересны варианты с шаблонами - лучше изучите вопрос и задавайте вопросы отдельно, готовое решение так не видел, самописные в разных организациях - попадались.
В дополнение, как совет по поводу:
Планируется, что программа будет передаваться между коллегами и не хочется создавать зависимостей.
Есть click-once, хоть он и очень неудачный на мой взгляд. Но, никаких заморочек по зависимостям и куче сборок не будет.

Ansible долго выполняет task setup

Периодически возникает проблема с ansible-playbook: очень долго "висит" на задаче setup. Подробный режим ничего внятного не сообщил:
TASK [setup] ******************************************************************* ESTABLISH LOCAL CONNECTION FOR USER: dmitry 127.0.0.1 EXEC /bin/sh -c '( umask 22 && mkdir -p "` echo $HOME/.ansible/tmp/ansible-tmp-1464268193.51-68811809432139 `" && echo "` echo $HOME/.ansible/tmp/ansible-tmp-1464268193.51-68811809432139 `" )' 127.0.0.1 PUT /tmp/tmpD6mRtI TO /home/dmitry/.ansible/tmp/ansible-tmp-1464268193.51-68811809432139/setup 127.0.0.1 EXEC /bin/sh -c 'LANG=ru_RU.UTF-8 LC_ALL=ru_RU.UTF-8 LC_MESSAGES=ru_RU.UTF-8 /usr/bin/python /home/dmitry/.ansible/tmp/ansible-tmp-1464268193.51-68811809432139/setup; rm -rf "/home/dmitry/.ansible/tmp/ansible-tmp-1464268193.51-68811809432139/" > /dev/null 2>&1'
Сколько это занимает по времени точно не засекал, но где-то порядка 10-15 минут, дальше выполнение происходит в нормальном темпе.
Сталкивался ли кто с таким, как лечить?


Ответ

Я думаю, что это весьма похоже на очень частую проблему "очень долго тупит midnight commander при запуске" (проблема разрешения имён - в hosts не прописан ip для hostname) - и у вас что-то не то с разрешением имён хоста. Плюс за эту версию -- что имя хоста разрешилось в 127.0.0.1 судя по вашему выводу.
Больше никакой конкретики не подскажу: если направление решения задачи угадано верно - то нужно знать, как у вас устроена сеть на предприятии - какие DNS-сервера, DHCP-сервера, какое окружение и т.п.

Установка свойств наследников стандартных элементов (например, FlowLayoutPanel)

При наследовании, например, от FlowLayoutPanel, в конструкторе прописываю свойства:
class myFlow : FlowLayoutPanel { public myFlow() { AutoSize = true; AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; } }
в дизайнере кидаю этот элемент на форму и, например, хочу вернуть обратно AutoSize=false. Вроде бы меняется и выглядит элемент на форме как нужно, но после ребилда и закрытия-открытия дизайнера формы свойство снова имеет значение, прописанное в конструкторе. Пробовал override InitLayout, но эффект тот же. Как правильно настраивать компоненты, чтобы в дизайнере можно было их поменять?


Ответ

[Browsable(true), EditorBrowsable(EditorBrowsableState.Always),DefaultValue(true) DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public override bool AutoSize { get { return base.AutoSize; } set { base.AutoSize = value; } }
Подсмотрел этот код в исходниках Panel от которого у FlowLayoutPanel наследуется свой AutoSize. Параметр DefaultValue(true) который собственно и делает то, что вам нужно добавил уже сам... Его существование и возможность использования подглядел в тех же исходниках Panel
AutoSizeMode думаю по аналогии должно сработать... Для корректной работы понадобится using System.ComponentModel;
Соответственно из конструктора установку значений данных свойств нужно удалить.

Зачем нужен __fspath__?

В версии Python3.6 запланирован (тем не менее об этом нигде прямо не говорится, кроме строчки "Python-Version") релиз нового волшебного метода __fspath__ (https://www.python.org/dev/peps/pep-0519). В описании сказано вроде бы ясно:
The goal is to facilitate the migration of users towards rich path objects while providing an easy way to work with code expecting str or bytes.
Цель - облегчить пользователям переезд на продвинутые объекты, представляющие файловые пути, при этом предоставляя удобный способ работы с кодом, который ожидает юникодных или байтовых строк.
Тем не менее, не совсем понятно несколько моментов:
Для кого это обновление? О каких пользователях идет речь? Каков будет типичный пример использования, будь то в библиотеках или в прикладных программах?
Обычно я, как обыкновенный пользователь, пишу что-то вроде:
project_path = os.path.realpath(os.path.dirname(__file__)) config_path = os.path.join(project_path, 'configs', 'sub_configs', 'my_super_config.ini') conf = open(config_path, 'r', encoding="utf-8")
и не вижу повода создавать из-за этого отдельные классы, представляющие пути. Даже если это будут классы вроде ConfigPath, ConcreteProjectConfigPath, то не совсем представляется, куда и зачем можно впихнуть новый метод.


Ответ

Потому что вызов str(path) чреват ошибками. str(obj) работает для любого объекта в Питоне, но не все объекты представляют пути. Пример из PEP 519: open(str(None), 'w') может молча создать файл, вместо выбрасывания ошибки. os.fspath(path) возвращает представление path, подходящее для файловой системы и позволяет избежать silent errors:
>>> import os >>> os.fspath(None) Traceback (most recent call last): File "", line 1, in TypeError: expected str, bytes or os.PathLike object, not
Примеры кандидатов для __fspath__ протокола: pathlib.Path, os.DirEntry (генерируются os.scandir()).

Ваш пример, можно так переписать:
from pathlib import Path import appdirs # $ pip install appdirs
path = Path(appdirs.user_data_dir(appname, appauthor)) config_path = path / 'configs' / 'sub_configs' / 'my_super_config.ini' conf = config_path.open(encoding="utf-8")
Если вы действительно данные из файла, расположенного относительно установленного модуля, хотите, то используйте pkgutil.get_data() или setuptools' pkg_resources.resource_string()
В данном случае разницы особой нет между os.path функциями и pathlib интерфейсом. Но в целом есть преимущества в использовании специальных объектов для путей вместо общих строк—из PEP 519
At issue is the fact that while all file system paths can be represented as strings or bytes, not all strings or bytes represent a file system path. This can lead to issues where any e.g. string duck-types to a file system path whether it actually represents a path or not.
Как продемонстрировано ошибкой наверху ответа иногда строки, которые не являются путями (str(None)), могут случайно как пути быть интерпретированы, а специальные объекты такие как pathlib.Path не имеют этого недостатка.
Плюс, специальный объект может предоставлять более богатый специальный интерфейс, например, path.read_text(). Существуют и существовали модули, использующие объекты для представления путей, например: path.py
На практике, если есть возможность использовать Питон 3 или поставить pathlib на Питон 2, то код, который с файловой системой работает, приятней с pathlib.Path/os.DirEntry писать. Вот примеры кода, где pathlib делает код более читаемым. Вот примеры, где одна и та же функциональность реализована с и без os.scandir()
Python Выбор последнего по дате файла из каталога Найти суммарный размер всех регулярных файлов в каталоге, рекурсивно обходя все подкаталоги

Правильная привязка данных и чтение из DataGrid wpf

Здравствуйте, решил узнать о грамотном размещении и чтении в и из datagrid в впф. Столкнулся с очень сложной ситуацией и решил ее очень, на мой взгляд плохим образом.
1) у меня есть подключенная база данных, все названия полей на англ. языке, а в представлении на datagrid нужно, что бы имена полей были на русском.
2) я решил использовать var, например var a = from b in db.clients select new { Имя = b.Name };
3) тут сразу вспомнил, что особо я с var не повеселюсь, поэтому сделал метод который сделает строку из п. 2 и установит datagrid.itemssource = a
4) ну и при чтении я столкнулся с еще большей проблемой... Не могу прочитать выделеную строку в класс datagridrow, он пытается привестись к анонимному типу... Но если я делаю переменную var, то и получаю на выходе object.
5) в итоге я использую вот что... dynamic changerow = dataGrid.SelectedValue; во время выполнения ошибок не вызывается, но на мой взгляд это ужасно. Прошу вас помочь мне понять как мне грамотно привязывать данные, что бы я мог без особых проблем читать и записывать данные в datagrid, если это возможно без привязки в xml. Спасибо!


Ответ

1.DataGrid. Все можно сделать гораздо проще. Правда, придется описывать каждый столбец в ручную. В принципе можно делать привязку, как Вы и сделали в пункте 3 datagrid.ItemSource = a; Правильнее все таки будет сделать в коде XAML. a - должно быть public. Тип столбца может быть и другим . Эта страница Вам в помощь.


Правильная привязка данных. Советую Вам поинтересоваться, что такое ORM, на пример EF, и что такое MVVM подход и как работает все в связке