Страницы

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

пятница, 14 июня 2019 г.

WPF. Image. Не отображает картинку

Есть картинка В конструкторе окна оно ее видит и отображает, при запуске программы - нет. Если инициализировать ее в конструкторе класса - пишет не удается найти ресурс, но как это, если в окне она ЕСТЬ!!!??? Помогите плиз!


Ответ

Исходя из /bin/debug/, думаю, вы делаете что-то не то.
Для начала, картинку нужно добавить в проект:

Убедитесь, что в качестве Build Action указано Resource, и отключено копирование в выходной каталог:

Теперь картинку можно подключать через путь внутри проекта:

Обратите внимание, что в проекте картинка лежит в каталоге Resources, и это соответствует пути в pack URI.

В Visual Studio 2015 отсутствует Bitmap

В Visual Studio 2015 с установленным XNA отсутствует System.Drawing и, следовательно, необходимый мне Bitmap. Что сделать, чтобы я смог использовать использовать Bitmap?
image http://image.prntscr.com/image/52433da102ff4fa29963756dd829ec97.png


Ответ

Namespace вверху должен быть:
using System.Drawing;
System.Drawing.Bitmap - это тип.
Чтобы это пространство имен было доступно, добавьте библиотеку System.Drawing.dll в References проекта.

Имплементация функционального интерфейса

Понимание интерфейса, как конструкции языка, до некоторых пор было мною вроде бы как усвоено. Столкнувшись с лямбда-выражениями это понимание рискует быть пересмотренным. Что я имею ввиду?
Интерфейс позволяет "объединить" в некотором смысле относительно разные классы и работать с ними под определенным углом (интерфейсом). Так или иначе, чтобы им (интерфейсом) воспользоваться, его необходимо имплементировать.
Функциональные интерфейсы, которые определяют один метод, ведут себя иначе? Их не нужно имплементировать, достаточно создать ссылку на них и присвоить этим ссылкам лямбда-выражение?
Мне интересен сам масштаб возможностей, который здесь открывается. Выходит просто ссылка на функциональный интерфейс внутри любого класса способна манипулировать объектами любого класса?


Ответ

Просто как пример, что же такое лямбда в Java
Лямбда
new AccidentsRequest(result -> {if (!result.has("error")) parseJSON(result);}, true);
ТРАХ-ТИБИДОХ, АХАЛАЙ-МАХАЛАЙ!!! И лямбда превращается... В анонимный класс!
new AccidentsRequest(new AsyncTaskCompleteListener() { @Override public void onTaskComplete(JSONObject result) throws JSONException { if (!result.has("error")) Content.this.parseJSON(result); } }, true);
Фактически лямбды в Java - это такой синтаксический сахар для анонимных классов с одним методом.

Как в JavaScript создать экземпляр класса на имени?

Доброго времени суток. Возник у меня вопрос, как создать объект, имея имя класса в переменной? Есть ли аналогичная возможность, как та, что реализована в php:
$className = 'MyClass'; $newObj = new $className();
Заранее благодарю за помощь.

По наводке @Other сделал так:
"use strict"; class Maxy { constructor() { this.Name = undefined; } Render() { console.log('Rendering...') } } let Maxies = { Mini1: class extends Maxy { }, Mini2: class extends Maxy { }, Mini3: class extends Maxy { } }; function CreateMini(Type) { let Mini = new Maxies[Type]; return Mini.Render(); } console.log(CreateMini('Mini2'));


Ответ

Классы, как и const, и let, не создают свойств в глобальном объекте, так что найти их по имени в переменной не выйдет. Использование eval может помочь, но всем знакомо правило: Don't use eval!

Можно специально создать свойство (или набросать простой плагин для Babel, который сам это будет делать):
window.Test = class Test{ notify(){ console.info('Yeah!'); } } let name = 'Test', app = new window[name]; app.notify();
Но, если честно, я не придумаю ситуации, где это нужно, ведь Enum-структуры нужно хранить в контейнере:
let np = { app: class{ notify(){ console.info('Yeah!'); } } }; let name = 'app', app = new np[name]; app.notify();

Способ получить координаты всех элементов массива без FOR

Есть массив arr с данными (по сути дела они не важны).
arr = np.array([[1,2,3],[4,5,6],[7,8,9]]) array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
Необходимо получить список координат центра каждого элемента массива. Предполагается что длина каждой ячейка равна 1. То есть нужно получить следующее:
(0.5, 0.5) (0.5, 1.5) (0.5, 2.5) (1.5, 0.5) (1.5, 1.5) (1.5, 2.5) (2.5, 0.5) (2.5, 1.5) (2.5, 2.5)
Делаю так:
for row in range(arr.shape[0]): for col in range(arr.shape[1]): print (row + 0.5, col + 0.5)
Собственно вопрос. Как избавиться от вложенных for друг в друга? Чую - наверняка есть какой-нибудь простой метод из Numpy


Ответ

Без for можно сделать вот так:
import numpy as np
arr = np.arange(3 * 3).reshape(3, 3)
grid = np.mgrid[:arr.shape[0], :arr.shape[1]] + 0.5
print(grid.reshape(2, -1).T)

Javascript. Что происходит в этом куске кода?

Первый раз вижу такой код.. не пойму, что тут происходит?
var DemoAppModel = (function (_super) { __extends(DemoAppModel, _super);
function DemoAppModel() { _super.call(this); }
DemoAppModel.prototype.auth = function () {}
return DemoAppModel; })(observable.Observable);
exports.DemoAppModel = DemoAppModel; exports.mainViewModel = new DemoAppModel();
Где про это можно прочитать?


Ответ

TL;DR: Это полифил для реализация наследования в версиях до ES6.

До преобразования транспилятором (скорее всего речь идет о TypeScript) этот код (как верно отметил @Pavel Mayorov) имел вид:
export class DemoAppModel extends observable.Observable { auth() { } } export var mainViewModel = new DemoAppModel();
Давайте разберемся что-здесь происходит строчка за строчкой:
// Создаем IIFE(*1), возвращающую конструктор класса DemoAppModel // Аргумент "_super" - конструктор родительского класса. var DemoAppModel = (function (_super) { // Выставляем правильную цепочку прототипов для вновь созданного // конструктора(*2). // Обратите внимание, "DemoAppModel" здесь - это функция определенная // строчкой ниже, а не функция из предыдущей области видимости(*3). __extends(DemoAppModel, _super);
// Определяем нашу функцию конструктор. function DemoAppModel() { // Вызываем родительский конструктор в контексте вновь созданного // экземпляра DemoAppModel. Это необходимо для правильной // инициализации переменных экземпляра, определенных через // родительский конструктор. _super.call(this); }
// Создаем новый метод для экземпляров DemoAppModel, который ничего // не делает. DemoAppModel.prototype.auth = function () {}
// Возвращаем созданный конструктор. return DemoAppModel; // Вызываем IIFE(*1) передавая конструктор родительского класса в качестве // аргумента. })(observable.Observable);
// Экспорт функции конструктора и созданного с его помощью экземпляра // для использования в других модулях. exports.DemoAppModel = DemoAppModel; exports.mainViewModel = new DemoAppModel();
Замечания:
IIEF(Immediately-invoked function expression) - функция, которая вызывается сразу же, как только она определена. В общем случае, функция __extends имеет вид (без полифила для ES<5):
function __extends(ctor, superCtor) { ctor.prototype = Object.create(superCtor.prototype, { constructor: { value: ctor, enumerable: false, writable: true, configurable: true } }); };
Что именно здесь происходит несколько выходит за рамки вопроса и требует отдельного дополнительного обсуждения. В JavaScript мы можем использовать функции до момента их определения благодаря "Поднятию определения".
Некоторое время назад я уже рассказывал, как именно работает прототипное наследование в JavaScript вот в этом ответе. Там есть чуть больше деталей о самой логике реализации прототипного наследования.

бесконечная анимация с задержками в SMIL

Добрый день уважаемые, подскажите пожалуйста, как в SMIL реализовать задержки в бесконечно повторяющейся анимации? Приведу пример
#work{ border: 1px solid #000; } #obgect{ animation: moveObject 4s linear infinite; } @keyframes moveObject{ 0%,100%{ transform: translateX(0); } 50%{ transform: translateX(100px); } }
На первом проходе всё хорошо. - После первой секунды шарик увеличиваеться, на 3-й секунде он приобретает свой изначальный размер, а дальше идет полное рассогласование. Мне необходимо понять как сделать так что б шарик менял свои размеры только с 2 по 3сек в бесконечном цикле. (CSS анимацию не трогаем) Собственно и вопрос - как реализовать повторяющиеся задержки в анимации бесконечного цыкла ?


Ответ

SMIL - это чистая декларативка. Нет переменных, функций и т.д Поэтому некуда запоминать текущее состояние в бесконечном цикле. Но вы хотели получить анимацию на чистом SMIL, поэтому я использовал возможность сделать цепочку последовательных анимаций и последняя анимация переходит к исполнению первой анимации begin="0s;an6.end", а в качестве пауз я поставил заглушки-анимации, которые ничего не делают, но участвуют в цепочке анимаций. Это строки с атрибутом - values="10;10"
Ниже тайминг последовательных анимаций. Зелёный прямоугольник - это горизонтальное перемещение шарика туда и обратно, заданное в стилях CSS
Увеличил немного длину и время пробега шарика для наглядности.

an1, an3, an4, an6 - идентификаторы заглушек- анимаций, которые обеспечивают паузы между анимациями an2 и an5 увеличения и уменьшения размеров шарика.

Как исправить ошибку Array 'f' cannot have a deferred shape?

Я пытаюсь решить СДУ с комплексной переменной методом Рунге-кутты 4 порядка, используя GNU Fortran Compiler. Как устранить ошибку "Array 'f' cannot have a deferred shape"?
program main integer, parameter :: n = 3, nsteps = 100 real, parameter :: a = 0.0, b =1.0 real :: x(0:n)
real :: d, hbar,W,omega0,omega,gamma1, E, delta d=3.335641E-30 hbar=1.0546e-34 omega = 2.482/(6.24e18*hbar) W = 1.25e10 omega0= 2.4743/(6.24e18*hbar) delta=0.0 gamma1= 1E15 E=(1/hbar)*W; x = (/1.0, 0.0, 0.0,0.0/) h = (b - a)/nsteps call rk4sys(n,h,x,nsteps) end program main

subroutine xpsys(n,x,f) complex, dimension (0:n) :: x, f integer n
f(0)= (-(0., 1.))*d*x(1)*E - x(2)*E+gamma1*x(4) ! 00+ f(1)= ((0., -1.)*(x(2)*(delta)+ d*E*(x(0)- x(3)))-gamma1*x(2)/2)!11 f(2)= (0., 1.)*(x(2)*(delta)+ d*E*(x(0)- x(3)))-gamma1*x(2)/2!10 f(3)= (0., 1.)*d*(x(1)*E- x(2)*E)-gamma1*x(3)!01
end subroutine xpsys
subroutine rk4sys(n,h,x,nsteps) complex :: x(0:n), f(:,:) real, allocatable :: y(:) integer :: i, k, n real :: h print *,0,x allocate (y(0:n), f(0:n,4)) out: do k = 1,nsteps call xpsys(n,x,f(0,1)) in1: do i = 0,n y(i) = x(i) + 0.5*h*f(i,1) end do in1 call xpsys(n,y,f(0,2)) in2: do i = 0,n y(i) = x(i) + 0.5*h*f(i,2) end do in2 call xpsys(n,y,f(0,3)) in3: do i = 0,n y(i) = x(i) + h*f(i,3) end do in3 call xpsys(n,y,f(0,4)) in4: do i = 0,n x(i) = x(i) + (h/6.0)* (f(i,1) + 2.0*(f(i,2) + f(i,3)) + f(i,4)) end do in4 print *, k, x end do out end subroutine rk4sys


Ответ

В процедуре rk4sys динамически-распределяемый массив f должен быть описан как allocatable
subroutine rk4sys(n,h,x,nsteps) complex :: x(0:n) complex, allocatable :: f(:,:) real, allocatable :: y(:) ...

Добавление политики конфиденциальности в приложение в Google Play Market

На днях пришло письмо от команды Google с таким содержанием: Action required: Include a link to a valid privacy policy on your app's Store Listing page and within your app. Когда я захожу в консоль разработчика там нужно указать ссылку на политику конфиденциальности. Вопрос заключается в следующем - где ее вобще взять? Ее как то получать специально надо?


Ответ

Для публикации политики конфиденциальности не имея собственного сайта или домена необходимо сделать следующее:
Создание статического веб-сайта. Одним из вариантов является GitHub Pages Создайте документ, описывающий, как вы планируете использовать необходимые разрешения. Добавьте документ на вебсайт. Добавьте ссылку на этот документ в Developer Console. Добавьте ссылку на этот документ в ваше приложение.

Можно ли с помощью Gitlab запустить bash-скрипт на сервере?

В целом задача проста и понятна. Нужно чтобы при пуше в ветку мастер на сервере запускался один bash-скрипт, при пуше в ветку qa - другой. Можно ли это реализовать средствами gitlab? (!Важно - не веб-хуком). Если да то как? Опишите что за чем делать. Если нет, то каким способом это можно сделать?


Ответ

Запускать разные скрипты для ветки master и для всех остальных можно с помощью директив except и only. Вот пример файла .gitlab-ci.yml
image: ...
stages: - build
build_branch: stage: build script: - ./build_branch.sh except: - master
build_master: stage: build script: - ./build_master.sh only: - master

Как подправить мобильное меню(показ)?

Привет всем.
В данный момент, когда делаю размер страницы < 992px и нажимаю на "Основное Меню", то появляется список подменю. Но, когда мы делаем размер страницы > 992px, то меню пропадает. (из-за slideToggle)
Также есть баг, когда ставлю медиа-запрос на > 992px, то в обычной версии страницы будут открыты оба меню, хотя должно быть открыто то, что мы нажали в моб. версии
Помогите подправить мобильное меню для адаптивки.
Еще раз, кто не понял: 1. Должно быть так изначально - prntscr.com/e7uyii Сейчас Основное закрыто. Проверьте jsfiddle.net/m5o8pwrd/21 2. Нужно, чтобы при клике в моб. версии на Второе меню(как сейчас prntscr.com/e7uzb1) в нормальной версии также было открыто Второе меню ( prntscr.com/e7uzx1 ), и также с Основным меню. 3. Присутствует баг анимации: когда я нажимаю на Основное меню в нормальном режиме, но нет слайда вниз, а просто появление списка... И, если я нажму на Второе меню, то анимация Основного меню также будет криво работать.
$(function() { $a = $('.side-menu > li > span'); $showlist = $('.side-menu > li > span + ul'); $a.on('click', function() { if ($(this).next().css('overflow', 'hidden')) { $(this).next().slideDown(300); $a.not(this).next().slideUp(300); } }); }); $(function() { $(".mobile").on('click', function() { $(".side-menu").slideToggle(300); }) }); * { padding: 0; margin: 0; } ul { list-style: none; } .main-container { display: flex; padding: 20px 0; } .sidebar { flex: 3; } aside a { color: #000; display: block; padding: 8px 30px; } .sidebar aside { margin-right: 50px; border: 1px solid #e2e1e1; cursor: pointer; background: white; margin-right: 35px; } .mobile { display: none; padding: 15px 20px; background: rgba(33, 32, 32, 0.83); color: #fff; letter-spacing: 5px; } .our-menu { padding: 15px 20px; background: rgba(33, 32, 32, 0.83); color: #fff; letter-spacing: 5px; } .invisible { display: none; } .sub-menu li { background: #f7f7f7; } .side-menu li { transition: all .3s; } .side-menu li .sub-menu li { font-style: italic; font-size: 16px; } .side-menu li:hover { background: #e8e8e8; } .side-menu > li > a, .side-menu > li > span { padding: 10px 18px; display: block; font-size: 18px; border-top: 1px solid #eeeeee; } .active { background: #e8e8e8; ; } .main { flex: 9; } @media (max-width: 992px) { .our-menu { display: none; } .mobile { display: block } .side-menu { display: none; } .main-container { display: block; } .sidebar aside { margin: 20px 0px; } .sub-menu { display: none; } }

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Minus nostrum explicabo rem dolorem vel vero culpa repellat ipsa maiores, optio alias tempora ducimus voluptates et neque unde. Quia necessitatibus, deserunt!
Vero eius molestias exercitationem non molestiae, sint aspernatur. Quos voluptatum modi vitae minima eos magni quas nesciunt architecto, odio vel explicabo officiis hic, voluptates ut. Repudiandae voluptatum maxime eos consequatur!
Quasi mollitia illo, aliquid rerum atque ipsum accusantium, maiores nulla, repudiandae quo libero rem. Mollitia dolore, ipsum asperiores praesentium voluptatum, aliquam laudantium magnam nemo, tenetur rerum iusto quo laboriosam ullam.
Expedita minima accusantium asperiores vel doloremque, unde est nulla dolore debitis dolorem, corrupti eos earum nemo, sunt, quos quidem perferendis. Harum enim praesentium vero quo id tempore, voluptatum aliquid cumque.
In repellat, vel impedit delectus fugiat eligendi eum expedita aspernatur velit hic provident veniam quaerat nostrum assumenda, id ducimus? Maxime eligendi dolores laboriosam. Molestias eius est dicta eaque in! Et!
Totam possimus officiis odio necessitatibus, ratione repellendus id nesciunt delectus explicabo, amet inventore quaerat, laborum mollitia earum quos nihil eaque at quisquam suscipit non officia unde. Excepturi dignissimos eaque, facere.
Fugiat voluptas nam repudiandae sed facere, iste, quae enim cum! Quaerat distinctio sed consequuntur neque dolores, necessitatibus totam animi cum veniam, ad obcaecati assumenda iste tempore, itaque nostrum eius sint!
Voluptatibus minima inventore consequatur voluptatem dolorem quia illum doloremque ducimus provident veritatis voluptates natus amet assumenda, ullam sequi delectus distinctio eum repudiandae quibusdam quod aspernatur voluptate, culpa itaque dolore. Nemo.
Possimus placeat ipsa asperiores doloribus, totam, unde provident illo, cumque, ut similique dolore iure. At ex explicabo iure officiis numquam eligendi aliquam tempore dolores aut distinctio quibusdam quaerat minima, obcaecati.
Quia voluptatem sed nam possimus qui ad doloremque quos placeat, sequi laboriosam sunt maiores distinctio repellat laborum, cum labore iste illo vitae. Aut expedita modi, tempora laborum! Neque, nulla, blanditiis.

Ссылка на стороннем редакторе: jsfiddle-m5o8pwrd-13


Ответ

Добавил в js $(window).resize(function()
$(function() { $a = $('.side-menu > li > span'); $showlist = $('.side-menu > li > span + ul'); $a.on('click', function() { if ($(this).next().css('overflow', 'hidden')) { $(this).next().slideDown(300); $a.not(this).next().slideUp(300); } }); }); $(function() { $(".mobile").on('click', function() { $(".side-menu").slideToggle(300); }) }); $(window).resize(function() { if ($(window).width() > 992) { $('.side-menu').removeAttr('style'); } if ($(window).width() < 992) { $('.sub-menu').removeAttr('style'); } }); * { padding: 0; margin: 0; } ul { list-style: none; } .main-container { display: flex; padding: 20px 0; } .sidebar { flex: 3; } aside a { color: #000; display: block; padding: 8px 30px; } .sidebar aside { margin-right: 50px; border: 1px solid #e2e1e1; cursor: pointer; background: white; margin-right: 35px; } .mobile { display: none; padding: 15px 20px; background: rgba(33, 32, 32, 0.83); color: #fff; letter-spacing: 5px; } .our-menu { padding: 15px 20px; background: rgba(33, 32, 32, 0.83); color: #fff; letter-spacing: 5px; } .invisible { display: none; } .sub-menu li { background: #f7f7f7; } .side-menu li { transition: all .3s; } .side-menu li .sub-menu li { font-style: italic; font-size: 16px; } .side-menu li:hover { background: #e8e8e8; } .side-menu > li > a, .side-menu > li > span { padding: 10px 18px; display: block; font-size: 18px; border-top: 1px solid #eeeeee; } .active { background: #e8e8e8; ; } .main { flex: 9; } @media (max-width: 992px) { .our-menu { display: none; } .mobile { display: block } .side-menu { display: none; } .main-container { display: block; } .sidebar aside { margin: 20px 0px; } .sub-menu { display: none; } }

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Minus nostrum explicabo rem dolorem vel vero culpa repellat ipsa maiores, optio alias tempora ducimus voluptates et neque unde. Quia necessitatibus, deserunt!
Vero eius molestias exercitationem non molestiae, sint aspernatur. Quos voluptatum modi vitae minima eos magni quas nesciunt architecto, odio vel explicabo officiis hic, voluptates ut. Repudiandae voluptatum maxime eos consequatur!
Quasi mollitia illo, aliquid rerum atque ipsum accusantium, maiores nulla, repudiandae quo libero rem. Mollitia dolore, ipsum asperiores praesentium voluptatum, aliquam laudantium magnam nemo, tenetur rerum iusto quo laboriosam ullam.
Expedita minima accusantium asperiores vel doloremque, unde est nulla dolore debitis dolorem, corrupti eos earum nemo, sunt, quos quidem perferendis. Harum enim praesentium vero quo id tempore, voluptatum aliquid cumque.
In repellat, vel impedit delectus fugiat eligendi eum expedita aspernatur velit hic provident veniam quaerat nostrum assumenda, id ducimus? Maxime eligendi dolores laboriosam. Molestias eius est dicta eaque in! Et!
Totam possimus officiis odio necessitatibus, ratione repellendus id nesciunt delectus explicabo, amet inventore quaerat, laborum mollitia earum quos nihil eaque at quisquam suscipit non officia unde. Excepturi dignissimos eaque, facere.
Fugiat voluptas nam repudiandae sed facere, iste, quae enim cum! Quaerat distinctio sed consequuntur neque dolores, necessitatibus totam animi cum veniam, ad obcaecati assumenda iste tempore, itaque nostrum eius sint!
Voluptatibus minima inventore consequatur voluptatem dolorem quia illum doloremque ducimus provident veritatis voluptates natus amet assumenda, ullam sequi delectus distinctio eum repudiandae quibusdam quod aspernatur voluptate, culpa itaque dolore. Nemo.
Possimus placeat ipsa asperiores doloribus, totam, unde provident illo, cumque, ut similique dolore iure. At ex explicabo iure officiis numquam eligendi aliquam tempore dolores aut distinctio quibusdam quaerat minima, obcaecati.
Quia voluptatem sed nam possimus qui ad doloremque quos placeat, sequi laboriosam sunt maiores distinctio repellat laborum, cum labore iste illo vitae. Aut expedita modi, tempora laborum! Neque, nulla, blanditiis.

Как сделать в SVG незамкнутый путь с двух сторон?

Возник такой вопрос, возможно ли в векторе создать фигуру из двух незамкнутых путей? Приведу пример

Здесь два полу-кольца. Но у меня не получается убрать обводку stroke с верхних части данной фигуры. Может кто-то посоветовать, как это реализовать. В дальнейшем эти два полукольца планируется анимировать. Должна происходить анимация постепенного закрашивания с верхней части в нижнюю.


Ответ

Можно пойти по другому пути. Нарисовать один патч вместо четырех. С одним патчем и анимировать при этом легче будет. Но надо точно узнать длину этого патча, чтобы потом использовать её в анимации посредством свойства stroke-dasharray Для определения длины пути нужно подставить своё значение строки path, начинающейся с d="m322....58z"

После нажатия на кнопку TotalLenght из модального окна берем длину нашего патча и подставляем в stroke-dasharray.

Обратите внимание, что вместо 2-х атрибутов stroke-dasharray использовано четыре. Для того, чтобы анимация шла из середины пути в разные стороны нужно разделить полную длину на пополам 827/2 = 413.5 Для окончания анимации подставляется полная длина пути 827 То есть эффект анимации достигается за счет увеличения длины штриха с 0 до полной длины и соответственно идет одновременное уменьшение пробела между штрихами от максимума до нуля.

Удалите код JavaScript и CSS, блокирующий отображение верхней части страницы, но скрипты итак внизу

PageSpeed Insights Рекомендует исправить обязательно:
Удалите код JavaScript и CSS, блокирующий отображение верхней части страницы

Хотя все скрипты итак стоят внизу страницы:

Не понимаю что может быть причиной, как можно исправить?
Если дело в количестве подключаемых библиотек, то проверяла другую подобную страницу (с десятком подключаемых скриптов) и все в порядке. async не помогает, да и проблем с ним много.
footer.tpl:

После скриптов контента нет.


Ответ

Как разобраться с блокирующим CSS я давал ответ вот тут. Дополнительно можете воспользоваться библиотекой loadCSS для загрузки неблокирующего CSS.
Куда вы разместите в странице ваши скрипты — в начало или конец документа — не имеет значения. В вашем случае совет следующий:
Во-первых, объединить все библиотеки-плагины и файл с их инициализацией в один файл, назовем его, к примеру, main.js
Во-вторых, загружать jQuery по событию load
function dlOnload() { var jq = document.createElement("script"); jq.src = "https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"; document.body.appendChild(jq); }
window.addEventListener("load", dlOnload, false);
В-третьих, запускать загрузку зависимых от jQuery файлов после его загрузки:
function dlOnload() { var jq = document.createElement("script"), mainScript; jq.src = "https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"; document.body.appendChild(jq);
jq.onload = function() { mainScript = document.createElement("script"); mainScript.src = "scripts/main.js"; document.body.appendChild(mainScript); } }
window.addEventListener("load", dlOnload, false);
И в-четвертых, всем скриптам, которым не важен порядок загрузки, добавить атрибут async

UPD: для динамической загрузки скриптов с возможностью кэширования в localStorage рекомендую воспользоваться basket.js. В вашем случае код будет выглядеть примерно таким образом:
basket .require({ url: 'path-to/jquery.js' }) .then(function () { basket.require( { url: 'path-to/jquery-ui.js' }, { url: 'path-to/jquery.fancybox.js' }, { url: 'path-to/jquery.fancybox.pack.js' }, { url: 'path-to/common.js' } ); }, function (error) { // Ошибка console.log(error); });

Как изменить переменную в зависимости от разрешения экрана? stylus

Использую stylus. Есть переменная $font-size = 1em, которая используется везде по проекту. Нужно, чтобы на мелких девайсах (@media screen and (max-device-width: 768px)), $font-size поменялся на 2em. Попробовала использовать if, не сработало


Ответ

Вы слишком многого хотите от препроцессоров. Насколько мне известно, такое их поведение не регламентировано правилами. Желаемого вами поведения можно добиться при помощи custom properties
:root { --fz: 2em; } .block { font-size: var(--fz); } @media (max-width: 700px) { :root { --fz: 1em; } }

This is text

При помощи препроцессоров надо создавать миксины с нужными вам свойствам, передавать в них переменные, а в медиа-выражениях вызывать миксины заново с новыми значениями переменных, чтобы переопределить свойства. Например так:
my-custom-block(fz) border-radius 5px border 1px solid font-size fz margin fz
my-custom-block(2em)
@media screen and (max-width: 700px) my-custom-block(1em)

Realm and Threading

Пишу проект. В качестве БД использую Realm. Это первый опыт с этой бд, поэтому за вопрос прошу не линчевать. Итак, к примеру, в качестве модели бд есть класс (все упрощенно, так как хочу передать суть вопроса как можно яснее):
public class QuoteText extends RealmObject { private long id; private String quoteText; ... }
Для изолирования слоя работы с этой бд я решила применить обобщенный вариант паттерна Repository. Написала интерфейс:
public interface QuoteRepository { List getListOfQuoteText(); }
И класс, реализующий этот интерфейс:
public class QuoteDataRepository implements QuoteRepository { private final Realm realm; @Override public List getListOfQuoteText() { return realm.where(QuoteText.class).findAll(); } }
Соответственно во фрагменте для получения списка QuoteText из бд:
QuoteDataRepository quoteDataRepository = new QuoteDataRepository(); List quoteTexts = quoteDataRepository.getListOfQuoteText();
Все бы ничего, но хотелось бы все эти запросы делать не в UI потоке. Как засунуть это все в другой поток? (Особенно интересно: можно ли совместить способы асинхронных запросов предлагаемые Realm (назнчаение слушателей, или запрос с использованием onSuccess(), onError() и прочее) и изоляцию слоя работы с бд).
Спасибо за помощь!
Правка: важен момент именно абстракции кода работы с бд и реализации асинхронных запросов.


Ответ

Красивее всего получится если вы будете соединять Realm + RxJava + Retrolambda.
Например вот такое может получиться:
public Observable> getFeedVkPostsSortedAsync(String field, Sort order) { return mRealm.where(VkPost.class) .equalTo(VkPost.FIELD_IS_IN_FEED, true) .equalTo(VkPost.FIELD_IS_IN_FAVORITES, true) .findAllSortedAsync(field, order) .asObservable() .filter(RealmResults::isLoaded) .filter(RealmResults::isValid) //опционально и на всякий случай отвязываем объекты от реалма и //возвращаем обычные объекты в обычном листе .flatMap(realmResults -> Observable.just(mRealm.copyFromRealm(realmResults))); }
Данный Observable, запущенный из основного потока выполнит запрос в БД асинхронно, отсеет объекты не удовлетворяющие двум условиям значений полей объектов (VkPost.FIELD_IS_IN_FEED, VkPost.FIELD_IS_IN_FAVORITES) и проверит что объекты возвращаемые полностью готовы для использования. И будет эмитить новую выборку при каждом изменении в ней.

Разделить фоновое изображение с 3D эффектом толщины

Я хочу разделить фоновое изображение. Например - такой оригинальный образ.

И хочу получить такой эффект:

Мой код:


Но я не могу найти любой способ, как разделить этот background с эффектом 3D толщины, с помощью CSS или jQuery.
Источник: Split background image with 3D thickness effect


Ответ

Вот этот 3D-подход, чтобы нарезать изображение на 3 части и сделать эффект толщины.
Это является масштабируемой техникой и зависит от:
3D-преобразования для вращения изображения и эффекта толщины техникой отступов - "padding technique" для сохранения пропорции элементов псевдо элементы, чтобы сделать толщину у каждой части изображения background image and background-position
Демо: 3d вращение и толщина изображения.

body{perspective:1000px;} .imgWrap{ position:relative; width:90%; margin:5% auto; padding-bottom:39%; transform: rotateY(25deg); transform-style:preserve-3d; } .imgWrap > div{ position:absolute; top:0; width:30.3%;height:100%; float:left; background-image:url('http://i.imgur.com/FhZxJJp.jpg'); background-size:auto 100%; transform-style:preserve-3d; outline: 1px solid transparent; /* prevent jagged edges in firefox */ } .imgWrap .left { left: 0; background-position: 3% 0; } .imgWrap .center{ left:34.83%; background-position: -97% 0; } .imgWrap .right { left:69.66%; background-position:-197% 0; } .imgWrap > div:before{ content:''; position:absolute; top:0;right:100%; width:10%; height:100%; background:inherit; transform-origin:100% 50%; transform:rotateY(-90deg); } .imgWrap .left:before { background-position: 0% 0; } .imgWrap .center:before{ background-position: -1001.3% 0; } .imgWrap .right:before { background-position: -2001.4% 0; }


Обратите внимание, что вам нужно, чтобы добавить префиксы поставщиков для поддержки браузера. Дополнительные сведения см. в разделе canIuse.
Перевод ответа: Split background image with 3D thickness effect @web-tiki

Если серверная часть написана на Java, можно ли написать клиент на js+html, не используя jsp.

Для учебных целей хочу создать приложение: форум, где участники могут регистрироваться, оставлять сообщения(чтобы сообщения сохранялись в бд). Приложение будет написано на Java. Можно ли обойтись без использования jsp, jsf, а только html и js? Буду очень благодарен ответившим.


Ответ

Можно. Вам успешно подойдет RESTfull архитектура.
Клиент с сервером по-прежнему общаются по http-протоколу, только теперь в ответах сервер отдает уже не готовые html-странички, а состояния (по сути данные) запрошенных вами ресурсов(URI) в формате json или реже xml. JS на клиенте разбирает эти ответы и сам строит необходимые странички.
Таким образом между клиентом и сервером нет больше никакой связи, кроме четко формализованного Rest Api. Причем клиент может быть реализован на чем угодно, HTML+JS это лишь частный случай. Это не новый, но очень популярный подход сейчас.

Как правильно передать массив в _stprintf_s()?

Почему в функцию передаётся TCHAR(&name)[100], а не TCHAR *name?
void CreateName(TCHAR(&name)[100], int number) { _stprintf_s(name, TEXT("Your number: %d"), number); }


Ответ

В документации Майкрософт функция _stprintf_s является макроопределением следующего вида
#define _stprintf_s swprintf_s
В свою очередь функция swprintf_s определяется как
template int swprintf_s( wchar_t (&buffer)[size], const wchar_t *format, ... ); // C++ only
То есть это шаблонная функция шаблонным параметром которой является размер массива. Поэтому массив, используемый в качестве аргумента передается функции по ссылке, чтобы функция могла определить размер массива.
Соответственно и функция CreateName объявляется свой первый параметр как ссылку на массив, который она далее передает в функцию _stprintf_s. Если бы она не принимала массив по ссылке, то не смогла бы вызвать функцию _stprintf_s
Для вызова функции CreateName нужно просто указать имя массива в качестве аргумента, как это делает в свою очередь сама функция при вызове функции _stprintf_s

C# события. Событие при зажатой кнопке

Нужно что бы выполнялся некоторой метод при зажатой(не нажатой, а именно зажатой) кнопке "A". А когда я ее отпускаю вызывался другой метод.
Есть вот такой код. Но почему то мелодия проигрывается всего 1 секунду, а потом останавливатся.
private void Window_KeyDown(object sender, KeyEventArgs e) { if (e.Key == Key.A) { PlaySound(); this.MyBotton.Background = Brushes.Black; } }
private void PlaySound() { wpalyer.URL = @"D:123.mp3"; wpalyer.controls.play(); }
private void Window_KeyUp(object sender, KeyEventArgs e) { if (e.Key == Key.A) { wpalyer.controls.stop(); this.MyBotton.Background = Brushes.White; } }


Ответ

Я бы посоветовал такой путь:
private void Window_KeyDown(object sender, KeyEventArgs e) { if (e.Key == Key.A && !e.IsRepeat) // проверка на повторение { PlaySound(); this.MyBotton.Background = Brushes.Black; } }

Инициализация переменной в конструкторе

Есть такой класс:
public class Game implements Screen {
private World world; private Renderer renderer;
public Game() { world = new World(); renderer = new Renderer(world); } }
Почему переменные инициализируются внутри конструктора, а не в месте их создания?
Например, можно просто написать:
private World world = new World();
В чем отличие таких способов инициализации?


Ответ

Плюсы использования инициализации переменной в строке с её объявлением:
Если имеется несколько конструкторов, то это позволяет избежать необходимости инициализировать переменную в каждом из конструкторов. При использовании анонимных классов нет возможности создавать их конструкторы - соответственно, инициализировать final поля класса можно только с помощью инициализации при объявлении и блока инициализации объекта.
Минусы такого использования:
Отсутствует возможность обработки исключений при инициализации. Отсутствует возможность проведения сколько-либо сложных вычислений (например, использование цикла for) при инициализации. В этом случае придётся воспользоваться конструктором или блоком инициализации объекта.

Как используя переменную %ProgramFiles% прописать путь до файла?

Первый код работает:
private const string _File = @"C:\Program Files\Folder\File.txt";
Второй код, вроде правильный, но не работает:
private const string _File = "\"%ProgramFiles%\\Folder\\File.txt\"";
Подскажите как поправить второй код, чтобы в системе x32 был путь:
C:\Program Files\Folder\File.txt
И в системе x64 такой же (без x86)
C:\Program Files\Folder\File.txt


Ответ

Файловое API естественно ничего не знает о переменных окружения. Поэтому вам нужно получить их значение. Проще всего воспользоваться методом Environment.ExpandEnvironmentVariables(), который резолвит все переменные окружения в заданной строке:
private const string _File = "\"%ProgramFiles%\\Folder\\File.txt\"";
var path = Environment.ExpandEnvironmentVariables(_File);
Также есть метод Environment.GetEnvironmentVariable(), который возвращает значение для указанной переменной.

VKsdk Android Studio получить id пользователя, под которым зашел

Нужно получить id пользователя под которым зашел в приложение, как это сделать?


Ответ

Довольно просто:
Хранится он здесь: VKAccessToken.currentToken().userId;
Вот так его можно безопасно узнать:
int getMyId() { final VKAccessToken vkAccessToken = VKAccessToken.currentToken(); return vkAccessToken != null ? Integer.parseInt(vkAccessToken.userId) : 0; }

Не могу получить значение аннотации у класса

Итак есть аннотация @MyAnno
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;
@Target({ElementType.FIELD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface MyAnno { String value(); }
Почему я не могу получить доступ к ее значению через код clazz.getAnnotation(MyAnno.class) с помощью метода value(),где Class clazz = object.getClass();
При работе с полями класса все ок, то есть этот код работает field.getAnnotation(MyAnno.class).value(), где field это элемент массива Field[] fields = clazz.getDeclaredFields()
P.S clazz.isAnnotationPresent(MyAnno.class) выдает true


Ответ

Предположим, есть такой класс:
@MyAnno("vvv") public class Anno { @MyAnno("xxx") public final int x = 0; }
Тестовый код для получения аннотации этого класса:
public static void main(String[] args) { Object object = new Anno(); Class clazz = object.getClass(); Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { MyAnno myAnno = field.getAnnotation(MyAnno.class); System.out.println("Field value: " + myAnno.value()); } MyAnno myAnno = clazz.getAnnotation(MyAnno.class); System.out.println("Class value: " + myAnno.value()); }
На экран выводится:
Field value: xxx Class value: vvv
Если использовать
Class clazz = object.getClass();
то придётся явно приводить тип:
MyAnno myAnno = (MyAnno)clazz.getAnnotation(MyAnno.class);
Потому что при использовании raw-type (Class) происходит стирание generic-типов в методах, из-за чего метод getAnnotation начинает возвращать просто Annotation

Как сделать бесконечный цикл в cmd?

Нужно бесконечно повторять некую команду. как это реализовать в командной строке?


Ответ

Если речь идёт непосредственно о командной строке
то стоит воспользоваться циклом for
for /l %q in (0) do echo Loop
Если же речь о bat-файле
в предыдущей команде можно удвоить знак процента:
for /l %%q in (0) do echo Loop
но лучше воспользоваться меткой и goto
:loop echo Loop goto loop

Как работает JIT-компилятор в .NET Framework?

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


Ответ

Когда среда CLR выполняет IL код, то происходит следующее: при вызове блока IL-кода JIT-компилятор проверяет и преобразует его в машинные команды которые он сохраняет в динамическом блоке памяти. Затем, он возвращается к структуре данных типа и заменяет адрес вызываемого метода адресом этого блока памяти и при следующем запросе повторная компиляция не будет выполнена, а будет использован уже скомпилированный код.
Теперь, непосредственно, ответ на ваш вопрос: нет, весь скомпилированный код хранится в динамической памяти, а это значит, что этот код уничтожается при выходе из приложения.
В тоже время, существует способ предварительной компиляции приложения в образ в машинном коде (Native Image) с помощью Native Image Generator (Ngen.exe)

Как отменить изменения внесенные при разрешении конфликта при слиянии веток?

Понадобилось слить одну ветку в другую. При слиянии обнаружился конфликт в одном файле. При его разрешении не так отредактировал файл. Как можно отменить изменения в файле? Чтобы он стал таким, как был сразу после попытки слияния, попробовал сделать так
git checkout myfile.c
на что получил ответ
error: path 'myfile.c' is unmerged
Остальное не пробовал, дабы случайно не навредить.


Ответ

Если предположить, что вы только исправили код и мерж не закончили, то проще всего сделать git merge --abort и начать мерж с начала.

VK api photos.getAlbums не возвращает ID альбома

Делаю запрос в ВК апи что бы получить список всех альбомов. Данные приходят все что должны прийти кроме ID альбома что очень важно в мое случае. что делал может кто сталкивался с этим?
запрос к апи.
@GET("photos.getAlbums") Observable getAlbums(@Query("owner_id") String ownerId, @Query("need_covers") int needCovers, @Query("access_token") String accessToken, @Query("photo_sizes") int needPhotoSizes);
получения данных и вывод в логи:
Log.e("AlbumsPresenter", "onNext "); Log.e("AlbumsPresenter", "onNext albumsResponce get(0).getId()"+albumsResponce.getResponse().get(0).getId()); Log.e("AlbumsPresenter", "onNext albumsResponce get(0).getThumbId()"+albumsResponce.getResponse().get(0).getThumbId()); Log.e("AlbumsPresenter", "onNext albumsResponce get(0).getOwnerId()"+albumsResponce.getResponse().get(0).getOwnerId()); Log.e("AlbumsPresenter", "onNext albumsResponce get(0).getDescription()"+albumsResponce.getResponse().get(0).getDescription()); Log.e("AlbumsPresenter", "onNext albumsResponce get(0).getTitle()"+albumsResponce.getResponse().get(0).getTitle()); Log.e("AlbumsPresenter", "onNext albumsResponce get(0).getSizes().get(0).getSrc()()"+albumsResponce.getResponse().get(0).getSizes().get(0).getSrc());
результат в консоли:
E/AlbumsPresenter: onNext E/AlbumsPresenter: onNext albumsResponce get(0).getId()0 E/AlbumsPresenter: onNext albumsResponce get(0).getThumbId()431783953 E/AlbumsPresenter: onNext albumsResponce get(0).getOwnerId()384281022 E/AlbumsPresenter: onNext albumsResponce get(0).getDescription()888888888888888888 E/AlbumsPresenter: onNext albumsResponce get(0).getTitle()8888888888888888888 E/AlbumsPresenter: onNext albumsResponce get(0).getSizes().get(0).getSrc()()https://pp.vk.me/c622926/v622926353/21ba5/8uK9JEFMF90.jpg


Ответ

Нашел в чем проблема. в документации Вконтакте написано что ID альбома будет называться в ответе "id". Но ответе от апи это поле называется "aid"

регулярки для проверки широты и долготы в градусах с десятичной дробью

Так понимаю, что у широты макс 8 символов, 6 из которых идут после точки и знак "-", а у долготы макс 9 символов, 6 идут после точки и знак "-".
preg_match('/^\d{2}.\d{6}$/D', $_GET['latitude']) preg_match('/^\d{3}.\d{6}$/D', $_GET['longitude'])
// 57.904683, -122.210420
Если верно, то как правильно указать необязательный "минус" в preg_match?


Ответ

Необязательный минус указывается в регулярном выражении с помощью квантификатора ?
^-?\d{2}\.\d{6}$
^ - начало строки -? - 1 или 0 минусов (квантификатор ? делает подшаблон необязательным) \d{2} - 2 цифры \. - точка (этот знак нужно экранировать, т.к. это спецсимвол, отлавливающий любой символ кроме знаков перевода строки) \d{6} - 6 цифр $ - конец строки (или \z, чтобы не использовать /D)

Не могу получить популярные аудиозаписи VK

получаю токен юзера и сразу пытаюсь получить
VKRequest audios = VKApi.audio().getPopular();
И получаю error 15 :( Читал, что сторонние разработчики не могут работать с аудио но как же тогда работает это
Что я не так делаю? И вообще почему для получения популярных аудиозаписей нужен токен? Мне их надо получать даже если пользователь не залогинился.


Ответ

PROFIT!
Я это сделал! Декомпилировал одно приложение и узнал какой сейчас используется хак.
main.xml



MainActivity.java
public class MainActivity extends Activity { public class VkontakteWebViewClient extends WebViewClient { @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { super.onPageStarted(view, url, favicon); MainActivity.this.parseUrl(url); } }
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); WebView kateWV = (WebView)findViewById(R.id.kateWebView); kateWV.getSettings().setJavaScriptEnabled(true); kateWV.clearCache(true); kateWV.setWebViewClient(new VkontakteWebViewClient()); CookieSyncManager.createInstance(this); CookieManager.getInstance().removeAllCookie(); kateWV.loadUrl(Auth.getUrl("2685278", Auth.getSettings())); }
public void parseUrl(String url){ if (url != null) { try { if (url.startsWith(Auth.redirect_url)) { if (!url.contains("error=")) { String[] auth = Auth.parseRedirectUrl(url); saveTokenToSharedPreferences(getApplicationContext(), Auth.VK_SDK_ACCESS, "scope=groups,audio,offline&https_required=1&expires_in=0&access_token=" + auth[0] + "&user_id=" + Long.parseLong(auth[1])); } startActivity(new Intent(MainActivity.this, AudioActivity.class)); finish(); } } catch (Exception e) { e.printStackTrace(); } } } public void saveTokenToSharedPreferences(Context ctx, String tokenKey, String code) { SharedPreferences.Editor edit = PreferenceManager.getDefaultSharedPreferences(ctx).edit(); edit.putString(tokenKey, code); edit.apply(); } }
Auth.java
public class Auth { public static final String VK_SDK_ACCESS = "VK_SDK_ACCESS_TOKEN_PLEASE_DONT_TOUCH"; public static String redirect_url;
static { redirect_url = "https://oauth.vk.com/blank.html"; }
public static String getUrl(String api_id, String settings) { return "https://oauth.vk.com/authorize?client_id=" + api_id + "&display=mobile&scope=" + settings + "&redirect_uri=" + URLEncoder.encode(redirect_url) + "&response_type=token" + "&v=" + "5.53"; }
public static String getSettings() { return "notify,friends,photos,audio,video,docs,status,notes,pages,wall,groups,messages,offline,notifications"; }
public static String[] parseRedirectUrl(String url) throws Exception { String access_token = Utils.extractPattern(url, "access_token=(.*?)&"); String user_id = Utils.extractPattern(url, "user_id=(\\d*)"); if (user_id == null || user_id.length() == 0 || access_token == null || access_token.length() == 0) { throw new Exception("Failed to parse redirect url " + url); } return new String[]{access_token, user_id}; } }
В итоге после авторизации через WebView в preferences будет сохранен токен
scope=groups,audio,offline&https_required=1&expires_in=0&access_token=тут_токен_юзера&user_id=тут_id_юзера
Далее можно работать с API VK. Лично у меня происходит переход в AudioActivity
Примерный код
VKRequest request = VkApi.audio().getPopular(); request.executeWithListener(new VKRequest.VKRequestListener() { @Override public void onComplete(VKResponse response) { //выводим json с музыкой в логи Log.d("vkmusic", response.responseString); } @Override public void onError(VKError error){ Log.d("err", error.toString()); } }); request.start();
Ну и все, можно юзать.
Результат

Кроссбраузерно определять конец страницы

Есть такого рода код:
$(window).scroll(function(){ if ($(window).scrollTop() == $(document).height() - $(window).height()) alert('Привет'); });
Прекрасно работает на десктопе. Но почему-то не работает в мобильной версии. Из мобилок у меня только iPhone 5C, так что девайсов на тест не велико, но и в режиме имитатции мобилок в Хроме, код тоже не хочет выполняться. Есть неколхозный и без костылей вариант кросбраузерно отслеживать конец страницы по скроллу?


Ответ

Попробуйте такой вариант с использованием кросс-браузерной функции определения высоты документа от James Padolsey
function getDocHeight() { var D = document; return Math.max( D.body.scrollHeight, D.documentElement.scrollHeight, D.body.offsetHeight, D.documentElement.offsetHeight, D.body.clientHeight, D.documentElement.clientHeight ); } $(document).ready(function() { $(window).scroll(function() { if ($(window).scrollTop() + $(window).height() == getDocHeight()) { alert("Конец страницы"); } }); }); #container { height: 1000px; width: 100px; background-color: red; }


Как работает рекурсивный generic?

У меня есть код, по которому я хочу разобраться, как работает рекурсивные generics. Смысл задачи в том, что-бы метод compareTo, принимал для сравнения, только объекты того типа, на котором он вызывается. То есть от класса Product наследуется Milk, и Phone, и объект Phone не должен принимать для сравнения в compareTo, объект Milk, только Phone. И есть место, которое я не как не могу понять. Это место Product> автор кода утверждает, что для правильной работы, необходимо параметризировать Product. Но код работает точно так же, если написать Product. Объясните пожалуйста, это я что-то не понимаю, или автор перемудрил. И если первое, то почему так?
class Product> implements Comparable { private int price;
Product(int price) { this.price = price; }
public int getPrice() { return price; }
@Override public int compareTo(T o) { return o.getPrice() - this.price; } }
class Milk extends Product { Milk(int price) { super(price); } }
class Phone extends Product { Phone(int price) { super(price); } }


Ответ

Использование T extends Product вместо T extends Product не препятствует созданию классов, у которых в качестве T участвует другой тип или T вообще не указан:
class Phone extends Product { ... }
class Chair extends Product { ... }
Однако в случае использования T extends Product не получится создать такой класс:
class CustomChair extends Product
потому что это приведёт к ошибке компиляции:
error: type argument Chair is not within bounds of type-variable T class CustomChair extends Product where T is a type-variable: T extends Product declared in class Product
Ошибка компиляции будет даже если класс Chair задан так:
class Chair extends Product { ... }
Так как в обоих случаях класс Chair не подходит в качестве T из-за требования T extends Product. Вот Chair extends Product подошло бы.
Можно сказать, что T extends Product задаёт более жесткие условия для T, чем T extends Product. Где-то это нужно, где-то - нет.
Например, если бы в классе Product были такие поля:
private T friend, friendOfFriend;
и такие методы:
public void setFriend(T t) { friend = t; friendOfFriend = t.getFriend(); }
public T getFriend() { return friend; }
public T getFriendOfFriend() { return friendOfFriend; }
То в случае использования T extends Product пришлось бы использовать
friendOfFriend = (T)t.getFriend();
для приведения Product к T, что чревато ClassCastException Например, при всё тех же class Chair extends Product и class CustomChair extends Product
Milk milk = new Milk(1); Chair chair = new Chair(10); chair.setFriend(milk); CustomChair customChair = new CustomChair(20); customChair.setFriend(chair); Chair c = customChair.getFriendOfFriend();
В реальных условиях, надеюсь, никто не пытается подружить стул с молоком, но всё же.
С T extends Product молоко получится подружить только с молоком:
Milk milk1 = new Milk(1); Milk milk2 = new Milk(2); Milk milk3 = new Milk(3); milk2.setFriend(milk3); milk1.setFriend(milk2); Milk m = milk1.getFriendOfFriend(); System.out.println(m.getPrice());

Изображение SVG внутри круга

Я хочу создать круг, внутри которого находится изображение. Я уже пробовал использовать pattern или filter, но ни один из них не дает ожидаемого результата.
Ниже приведен код:

Моя цель - сохранить круг и создать фоновое изображение внутри него, что-то вроде атрибута CSS background-image.
Перевод вопроса: SVG image inside circle


Ответ

pattern будет работать. Вам просто необходимо указать размер , так как в отличии от HTML, SVG-изображения по умолчанию имеют ширину и высоту отличающуюся от нуля. Кроме того, если вы хотите, чтобы изображение масштабировалось вместе с кругом, то вам следует указать viewBox для pattern.

Перевод ответа: @Paul LeBeau

Как перезагрузить страницу при нажатии на кнопку “НАЗАД” в браузере?

В кратце. Пользователь залогинился. Гулял по сайту. Затем вышел (нажал выход).
Его кинуло на страницу авторизации. Это нормально. Но когда пользователь жмет стрелку "НАЗАД" в браузере, то ему открываются ранее просмотренные страницы сайта (где он был залогинен).
Получается его информация в опасности и может быть доступна третьим лицам.
Как сделать так, что бы при нажатии на кнопку "НАЗАД" страница обновлялась и соотвественно возвращалась на авторизацию.


Ответ

Запрет кеширования(http)
Изначально страницы нужно отдавать с заголовком:
Cache-Control: no-cache, max-age=0, must-revalidate, no-store
Каждый их этих атрибутов заголовка предназначен для запрета кеширования.
Meta-теги(html)

Очистка истории(js)
Очень ненадёжно, код после history.go никто не хочет выполнять)
history.go(-(history.length-1)); location.href='/login';

Отличия NestedScrollView от ScrollView

В чем отличия NestedScrollView от ScrollView, если можно на примерах. Спасибо


Ответ

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

Сортировать элементы с помощью jquery

Есть элементы со значениями

  • 1%
  • 1%
  • 80%
  • 10%
  • 1%

хочу отсортировать список
$(document).ready(function() { var $elements = $('li progress value'); var $target = $('.error_sorting'); $elements.sort(function (a, b) { var an = $(a).text(), bn = $(b).text(); if (an && bn) { return an.toUpperCase().localeCompare(bn.toUpperCase()); } return 0; }); $elements.detach().appendTo($target); });
но видимо, что-то делаю не так. не сортирует.


Ответ

Непонятно, что Вы рассчитываете получить таким селектором: $('li progress value')
$(document).ready(function() { var $elements = $('ul.error_sorting > li'); var $target = $('.error_sorting'); $elements.sort(function(a, b) { var an = parseInt($(a).find('progress').attr('value')), bn = parseInt($(b).find('progress').attr('value')); return an - bn; }); $elements.detach().appendTo($target); });

  • 1 %
  • 1 %
  • 80 %
  • 10 %
  • 1 %

Как сделать чтобы не дублировать код в JS?

Здравствуйте.
Подскажите, как сделать, чтобы не дублировать этот код:
var showError = function(el) { el.parentNode.classList.remove('error'); el.parentNode.classList.add('success'); el.nextElementSibling.InnerHTML = element.dataset.error; } var showSuccess = function(el) { el.parentNode.classList.remove('error'); el.parentNode.classList.add('success'); el.nextElementSibling.InnerHTML = ''; }


Ответ

function getClassSwitcher(classOff, classOn, getErrorMsg) { return function(el) { el.parentNode.classList.remove(classOff); el.parentNode.classList.add(classOn); el.nextElementSibling.innerHTML = getErrorMsg(); }; }
const showError = getClassSwitcher('success', 'error', () => element.dataset.error); const showSuccess = getClassSwitcher('error', 'success', () => '');
Вариант попроще:
function toggleClasses(el, on, off) { el.classList.remove(off); el.classList.add(on); }
const showError = function(el) { toggleClasses(el.parentNode, 'error', 'success'); el.nextElementSibling.innerHTML = element.dataset.error; } const showSuccess = function(el) { toggleClasses(el.parentNode, 'success', 'error'); el.nextElementSibling.innerHTML = ''; }

Условия на тип возвращаемого значения метода при использовании await?

Есть метод:
public async T Method() { T result = await doSomeStuff();
return result; }
Какие условия должны быть выполнены для T, чтобы этот метод можно было вызвать:
public async void AnotherMethod() { await Method(); }


Ответ

По идее, await можно использовать для любого типа, в котором есть метод GetAwaiter, возвращающий реализацию интерфейса INotifyCompletion
public AlexsAwaiter GetAwaiter() { return new AlexsAwaiter(); }
class AlexsAwaiter : INotifyCompletion { public bool IsCompleted { get { ... } } public void OnCompleted(Action continuation) { ... } public void GetResult() { ... } }
Тип, возвращаемый GetResult и будет возвращаться из await
Подробнее лучше почитать например в книге
Дэвис Д. - Асинхронное программирование в C# 5.0 - 2013г.
или тут

Восстановление удаленных файлов windows

Здравствуйте. Произошла катастрофа. Нужно было переустанавливать Windows, и прежде чем сделать это я залил архив размером 10гб на один из файлообменников сроком на 5 дней. К сожалению, сыграл тот самый случай: Я забл скачать этот архив. Соответственно, все данные с файлообменника были стерты. Если ли надежда восстановить файлы (я знаю название папок и пару имен фотографий) спустя 7 дней после переустановки Windows? Делал я полную переустановку, абсолютно все удалил. Я накачал кучу программ восстанавливающие удаленные файлы, но все тщетно. Какие варианты, кроме как "все пропало" вы можете еще предложить? В том архиве было все, абсолютно все.


Ответ

Можно попробовать различные программы для восстановления удалённых файлов. Мне нравится Recuva. Однако, времени прошло много, поэтому, скорее всего, большая часть данных уже перезаписана и восстановить удастся немногое.
Другой вариант - попытаться обратиться в поддержку файлообменника с предложением купить этот файл (ну какой-то их тариф, который позволяет хранить файлы, или ещё что-то - в общем, уже с ними разбираться). Фишка в том, что для подобных сайтов может быть важно отсутствие фрагментированности на дисках, что означает, что физическое удаление файлов происходит намного реже, чем их убирание из каталога. Потенциально у них есть неудалённый файл, но просто так они его точно не отдадут.
А вообще, при установке системы надо делить диск хотя бы на 2 раздела - один под систему, а второй - под данные. А ещё можно использовать кучу сервисов, в которых время хранения файлов не ограничено.
filemail
Из любопытства пообщался с их поддержкой, а именно
Njål Active in the last 15m CEO 12:00 am in Oslo, Norway CEO and one of the founders of Filemail. Living in Oslo, Norway with my ripped wife and two awesome kids. Keepin it real by doing some support every day 👊
закончили на этом:
I can not go into technical details with you, sorry. If you want us to pursuit this any more - the starting price would be $5.000. We would have to make major traffic redirection and a considerable effort recovering these files. And we can not guarantee the result.
Хотя есть подозрение, что если бы я назвал ссылку, реакция могла бы быть другой. Мне кажется, что усилия по поиску несколько преувеличены, а вместе с ними и цена, так что можно попробовать поторговаться (но уже не мне, естественно).
Вот скриншоты всей переписки:

Как добавить pkgconfig в CMakeLists.txt

Хочу заменить часть скриптов на Python более быстрыми аналогами на C++. В первую очередь интересует SAX парсеры из libxml++-3.0 В дистрибутиве есть папка examples. Скомпилировать все примеры сразу получилось командой make check. Теперь нужно открыть содержимое examples/sax_parser в какой-нибудь IDE и запускать оттуда. Как выяснилось, это можно сделать десятками способов и все они нетривиальные. В README к библиотеке упомянута только команда
$ pkg-config libxml++-3.0 --cflags --libs -I/usr/local/include/libxml++-3.0 -I/usr/local/lib/libxml++-3.0/include -I/usr/include/libxml2 -I/usr/include/glibmm-2.4 -I/usr/lib/x86_64-linux-gnu/glibmm-2.4/include -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/sigc++-2.0 -I/usr/lib/x86_64-linux-gnu/sigc++-2.0/include -L/usr/local/lib -lxml++-3.0 -lxml2 -lglibmm-2.4 -lgobject-2.0 -lglib-2.0 -lsigc-2.0
Как записать результат её выполнения во что-нибудь вроде CMakeLists.txt?


Ответ

Если нужно именно добавить вывод pkg-config в cmake проект: У Cmake есть модуль PkgConfig, который запускает и парсит вывод одноименной утилиты
find_package(PkgConfig) pkg_search_module(LIBXML REQUIRED libxml++-3.0)
Вторая строка запишет в переменные все нужные данные(каталоги с хидерами, каталоги с библиотеками, флаги, список библиотек для линковки и т.д.) Теперь просто используй переменные для указания всего нужного:
include_directories(${LIBXML_INCLUDE_DIRS}) compile_options(app_name ${LIBXML_CFLAGS} link_libraries(app_name ${LIBXML_LIBRARIES}
Писал по памяти, может где неправильно что, поищи документацию FindPkgConfig

Bash: путь с пробелами в массиве

Есть массив с путями и цикл его переберающий (песочница):
paths=( "~/.config/sublime-text-3/Installed Packages" ~/.config/sublime-text-3/Local ~/.config/sublime-text-3/Packages )
for path in ${paths[@]} do echo ${path} done
Результат:
~/.config/sublime-text-3/Installed Packages /home/cg/root/.config/sublime-text-3/Local /home/cg/root/.config/sublime-text-3/Packages
В результате видно, что возникает проблема с пробелом в пути ~/.config/sublime-text-3/Installed Packages и Packages воспринимается как элемент массива.
Как её можно исправить?
Единственное, что пришло в голову, это экранировать пробел:
paths=( ~/.config/sublime-text-3/Installed\ Packages ~/.config/sublime-text-3/Local ~/.config/sublime-text-3/Packages )
Но результат тот же.

P. S. Если код в песочнице не работает, то нужно очистить куки; по крайней мере у меня возникали какие-то проблемы в Chrome с этим.


Ответ

можно поместить в двойные кавычки подстановку массива:
for path in "${paths[@]}"

да и при обращении к отдельным строкам двойные кавычки не помешают (чтобы опять-таки не столкнуться с разделением на подстроки по пробелам):
"${path}"

Как сокращать ссылки vk.cc на python?

Вопрос по сокращению ссылок через vk.cc, подозреваю что что-то пропустил, в ответ получаю: '3975786006921profile.css,page.css,profile.js,page.js067628Невозможно сократить эту ссылку.57500570' На любой адрес. API вроде нет, расширение для Хрома у меня не завелось, не знаю работает ли оно сейчас, код ниже:
import requests import re
def get_form_action(html): form_action = re.findall(r' auth_session = requests.Session()
def authorization(phone, password): url = 'https://m.vk.com' response = auth_session.get(url) login_form_action = get_form_action(response.text) if not login_form_action: raise Exception('VK changed login flow') login_form_data = { 'email': phone, 'pass': password } response = auth_session.post(login_form_action, login_form_data)
def get_short(link): url = 'https://vk.com/cc?act=shorten&al=1&link='+link headers = {"Content-Type": "application/x-www-form-urlencoded", "X-Requested-With": "XMLHttpRequest"} response = auth_session.post(url=url, headers=headers) return response.text
Может кто делал серверную реализацию сокращения ссылок через вк? Буду благодарен за помощь!


Ответ

Накидал пример того как можно авторизоваться и воспользоваться vk для получения короткой ссылки:
def get_short_link_from_vk(login: str, password: str, link: str) -> str: """ Функция для получения короткой ссылки используя сервис vk.
"""
def get_form_action(html: str) -> str: """ Функция вернет ссылку для запроса авторизации
"""
import re form_action = re.findall(r' import requests session = requests.Session()
# Без авторизации не получится воспользоваться страницей укорачивания ссылок url = 'https://m.vk.com' rs = session.get(url) print(rs)
login_form_action = get_form_action(rs.text) if not login_form_action: raise Exception('VK changed login flow')
login_form_data = { 'email': login, 'pass': password, } rs = session.post(login_form_action, login_form_data) print(rs)
# Страница нужна чтобы получить hash для запроса rs = session.get('https://vk.com/cc')
import re match = re.search(r"Shortener\.submitLink\('(.+)'\)", rs.text) if match is None: raise Exception('Не удалось получить hash для Shortener')
shortener_hash = match.group(1)
# Данные для POST запроса для получения короткой ссылки data = { 'act': 'shorten', 'link': link, 'al': '1', 'hash': shortener_hash, }
headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0', 'X-Requested-With': 'XMLHttpRequest', 'Content-Type': 'application/x-www-form-urlencoded', }
rs = session.post('https://vk.com/cc', headers=headers, data=data) print(rs)
from bs4 import BeautifulSoup root = BeautifulSoup(rs.content, 'lxml')
a_short_link = root.select_one('.shortened_link.shorten_list_header > a[href]') return a_short_link['href']
Использование:
LOGIN = '' PASSWORD = '' link = 'https://ru.stackoverflow.com/questions/648230'
short_link = get_short_link_from_vk(LOGIN, PASSWORD, link) print(short_link)
link = 'https://git-scm.com/book/ru/v1/%D0%9E%D1%81%D0%BD%D0%BE%D0%B2%D1%8B-Git-%D0%9F%D1%80%D0%BE%D1%81%D0%BC%D0%BE%D1%82%D1%80-%D0%B8%D1%81%D1%82%D0%BE%D1%80%D0%B8%D0%B8-%D0%BA%D0%BE%D0%BC%D0%BC%D0%B8%D1%82%D0%BE%D0%B2' short_link = get_short_link_from_vk(LOGIN, PASSWORD, link) print(short_link)
Консоль:
https://vk.cc/6sYwPq https://vk.cc/5AJUvX
Использовал сторонние модули:
pip install requests pip install bs4

Обновление базы данных dataGridView с адаптером С#

Приветствую. Есть БД. Таблица из базы отображается в dataGridView. Пытаюсь отредактировать и сохранить таблицу из dataGridView в БД через адаптер.
public static SqlDataAdapter Createadapter() { SqlConnection conn = new SqlConnection(connectionString); SqlDataAdapter adapter = new SqlDataAdapter(); SqlCommand updateCommand = new SqlCommand(@"UPDATE customers SET customer_phone = @phone, customer_Email = @MAIL",conn); updateCommand.Parameters.Add(@"phone", SqlDbType.NChar, 20, "customer_phone"); updateCommand.Parameters.Add(@"MAIL", SqlDbType.NVarChar,50, "customer_Email"); adapter.UpdateCommand = updateCommand;
return adapter; }
Возникает такая проблема - абсолютно все значение столбца принимают значение отредактированной ячейки этого столбца.
Подскажите как исправить? Спасибо


Ответ

Спасибо @Mr Scapegrace! поменял строку команды на:
SqlCommand updateCommand = new SqlCommand(@"UPDATE customers SET customer_phone = @phone, customer_Email = @MAIL WHERE (id = @ID)",conn);
Добавил :
SqlParameter parametr = updateCommand.Parameters.Add(@"ID",SqlDbType.Int,10,"id"); parametr.SourceVersion = DataRowVersion.Original;
И все заработало!