Есть функция, которая завершает программу, выполняя занесение отладочной информации в файл лога: void crash(const char *const _fstr, ...)
{
if ( (_fstr != NULL) && (strlen(_fstr) > 0) )
{
FILE *f = fopen(CRASH_LOG_FILE_NAME, "a");
fprintf(f, _fstr, ???);
fclose(f);
} abort();
}
Я хочу сделать, чтобы в функцию crash() передавалась строка формата и какое-то количество аргументов. Ситуации бывают разные. При некоторых крашах в файл желательно заносить не только строку с описанием проблемы, но еще и ряд кодов, например GetLastError() и WSAGetLastError() Как это сделать?
Ответ
Вам нужно использовать функцию vfprintf, а передавать ей аргумент типа va_list, который получаете в своей функции примерно как void crash(const char *const _fstr, ...)
{
va_list ap;
va_start(ap, _fstr); ...
vfprintf(f,_fstr,ap); ...
va_end(ap);
Запускаю фаил в командной строке с такими аргументами: python test.py -f a.jpg b.jpg -t png
как получить список файлов a.jpg b.jpg ? использую библиотеку argparse
Ответ
Что бы получить аргументы как список нужно использовать nargs='+'. В документации описано как можно интерпретировать количество параметров используя nargs https://docs.python.org/2/library/argparse.html#nargs import argparse
parser = argparse.ArgumentParser(description='description')
parser.add_argument('-l', '--list', nargs='+') if __name__ == '__main__':
args = parser.parse_args()
print(args)
При вызове скрипта с параметрами получим следующий вывод python test.py -l q a 1
Namespace(list=['q', 'a', '1'])
Всем привет! Столкнулся с проблемой верскти не совсем обычного слайдера диапазона значений.
До сегодняшнего дня думал, что умею неплохо верстать, оказалось это не совсем так :) Друзья подскажите, как мне заверстать такой элемент. Пробовал через transform: skewY с псевдоэлементом , но это не лучший способ,- результат не совсем тот. В общем, друзья, подтолкните меня на правильную мысль, или дайте ссылочку на пример такого элемента
Спасибо!
Есть запрос: select
nvl(extractvalue(xmltype(p.src_doc, 871), '//*:' || pd.name),
extractvalue(xmltype(p.src_doc, 871), '*/*[local-name()="AdditionalData"][*[local-name()="Name"]="' || pd.name || '"][1]/*[local-name()="Value"]')) as elm_value,
pd.guid as param_guid,
p.guid as pmnt_guid
from
payments p
join services s
on p.srv_guid = s.guid
join parameters_definitions pd
on s.guid = pd.srv_guid
left outer join pmnt_elements_values elm
on p.guid = elm.pmnt_guid and pd.guid = elm.param_guid
where
elm.guid is null and p.src_doc is not null;
В принципе корректно парсит XML в clob, но иногда может возникнуть исключение: ORA-31011: сбой разбора XML
ORA-19202: Возникла ошибка при обработке XML
LPX-00601: Invalid token in: '//*: PAYMENTTYPE '
31011. 00000 - "XML parsing failed"
*Cause: XML parser returned an error while trying to parse the document.
*Action: Check if the document to be parsed is valid.
Проблема в том, что некоторые XML корректны, некоторые нет, таблица довольно объемна. Единого примера XML тоже дать не могу, так как все XML-документы корректны в рамках своей схемы, но по понятным причинам имеют разные значения в нодах, разные неймспейсы и атрибуты в некоторых нодах. Можно ли как-то обойти/проигнорировать/обработать исключения разбора XML? Можно ли хотя бы как-то получить понимание где конкретно и на чем разваливается парсер? Версия: Oracle Database 11g Enterprise Edition.
Ответ
Надо обернуть всю логику по разбору XML в функцию, которая обработает исключения и запишет полную информацию об ошибках, например, в таблицу. Как-то так: create table parseErrors (guid raw (16), errm varchar2 (4000), created timestamp); create or replace function myXmlParser (docGuid raw, doc clob) return varchar2 is
procedure saveParseError (guid raw, errm varchar2) is
pragma autonomous_transaction;
begin
insert into parseErrors values (guid, errm, systimestamp);
commit;
end ;
begin
-- **здесь необходимая логика, в которой может возникнуть ошибка**
return xmlType (doc).getStringVal ();
exception when others then
saveParseError (docGuid, sqlerrm||chr(10)||sys.dbms_utility.format_error_backtrace());
return 'errorneous';
end myXmlParser;
/
Выборка для теста (вместо sys_guid() должна быть колонка с GUID из запроса): select myXmlParser (sys_guid(), 'some data') from dual union all
select myXmlParser (sys_guid(), 'illegal XML syntax') from dual
;
выведет: RESULT
------------------------
some data
errorneous
Kакие были ошибки: set lines 999
col errm for a40 wrapp
select * from parseErrors; GUID ERRM CREATED
-------------------------------- ---------------------------------------- -----------------------------
7106268B980F02D3E0530A01A8C04FBB ORA-31011: XML parsing failed 2018-07-15 12:32:41,204757000
ORA-06512: at "SYS.XMLTYPE", line 272
ORA-06512: at "DB.MYXMLPARSER", line 10
PS В вопросе мало информации по локализации причины ошибки, но думаю ссылки на похожие топики тут и тут будут полезны.
У меня есть строка $path = '/user/5'; Мне нужно извлечь число 5 из нее, я могу проверить ее регулярным выражением: preg_match('/\/user\/[0-9]/', $path, $matches) Но в данном случае $matches будет равен $path (var_dump $matches): array(1) { [0]=> string(7) "/user/5" } Как максимально быстро извлечь 5?
Ответ
В своем выражении, вы не объявляете группировку ([0-9]+), нужно брать в круглые скобки, попробуйте так: $path = '/user/5'; preg_match('~/user/([0-9]+)~', $path, $matches); echo $matches[1];
Собственно код: extern crate num_traits; pub trait DigitCount {
fn decimal_digit_count(&self) -> usize;
} impl > DigitCount for T {
fn decimal_digit_count (&self) -> usize {
if self.is_zero() {
1
} else {
self.into().abs().log10().trunc() as usize + 1
}
}
}
Метод decimal_digit_count должен вызываться для любого целого значения и возвращать количество десятичных разрядов в нём: println!("{}", 123u64.decimal_digit_count());
Вопрос: как правильно записать преобразование T → f64 для последующего вызова методов abs, log10, trunc? В текущем виде компилятор требует аннотацию типа для into(), но если её подставить (into::()), то говорит, что ожидается 0 параметров типов.
Ответ
У самого метода и правда нет типового параметра, потому что он есть у типажа: pub trait Into {
fn into(self) -> T;
}
Первый вариант исправления - просто явно указать через промежуточную переменную какой тип мы в итоге хотим получить: let f: f64 = self.into();
f.abs().log10().trunc() as usize + 1
(playpen) Второй вариант - использовать UFCS форму вызова метода с явным обозначением T у типажа: Into::::into(self).abs().log10().trunc() as usize + 1
(playpen)
Метод decimal_digit_count должен вызываться для любого целого значения и возвращать количество десятичных разрядов в нём
На всякий случай еще добавлю что преобразование в f64 реализовано не для всех целых типов. Такое преобразование обязано всегда заканчиваться успехом, что невозможно, например, для u64 или i128 из-за невозможности вместить весь диапазон значений.
Есть job, который запускает процедуру с входящими параметрами через программу. Как запустить job вовремя ее выполнения чтобы она стала в очередь и начала отрабатывать после завершения первой, но уже с другими параметрами? job запускаю след образом dbms_scheduler.set_job_argument_value('GPIMS.JOB_UPD_GP_ADDR_MAPP',1,IN_GP_ID);
dbms_scheduler.set_job_argument_value('GPIMS.JOB_UPD_GP_ADDR_MAPP',2,to_char(P_GP_STATUS_DATE));
dbms_scheduler.enable('GPIMS.JOB_UPD_GP_ADDR_MAPP');
Создание job begin
dbms_scheduler.create_job('GPIMS.JOB_UPD_GP_ADDR_MAPP',
program_name => 'GPIMS.PROGRAM_UPD_GP_ADDR_MAPP',
auto_drop => FALSE);
end;
Создание программы begin
sys.dbms_scheduler.create_program(program_name => 'GPIMS.PROGRAM_UPD_GP_ADDR_MAPP',
program_type => 'STORED_PROCEDURE',
program_action => 'GPIMS.PKG_GLOBAL_PROBLEM.UPD_GP_ADDR_MAPP',
number_of_arguments => 3,
enabled => false,
comments => '');
sys.dbms_scheduler.define_program_argument(program_name => 'GPIMS.PROGRAM_UPD_GP_ADDR_MAPP',
argument_position => 1,
argument_name => 'IN_GP_ID',
argument_type => 'VARCHAR2',
default_value => '');
sys.dbms_scheduler.define_program_argument(program_name => 'GPIMS.PROGRAM_UPD_GP_ADDR_MAPP',
argument_position => 2,
argument_name => 'P_GP_STATUS_DATE',
argument_type => 'DATE',
default_value => '');
sys.dbms_scheduler.define_program_argument(program_name => 'GPIMS.PROGRAM_UPD_GP_ADDR_MAPP',
argument_position => 3,
argument_name => 'OUT_MSG',
argument_type => 'VARCHAR2',
default_value => '');
sys.dbms_scheduler.enable(name => 'GPIMS.PROGRAM_UPD_GP_ADDR_MAPP');
end;
Ответ
Так нельзя делать. Невозможно запустить once Job, который уже выполняется.
Для этого есть цепочки (job chains), но передать к каждому звену цепочки свои параметры также не представляется возможным. Можно передать каждому звену мета данные, например: job_name, job_subname, как формальные параметры. Они будут замещены актуальными значениями для выполняемой задачи и соответственно звена задачи. Далее определить эти же данные как ключ в таблице для параметров. Подготовим схему: create table myJobInfo (beg timestamp, end timestamp, info varchar2 (256));
create or replace type myJobArgs as object (
jobName varchar2 (32), jobStepName varchar2 (32), argChar varchar2 (64), argDate date);
/
create table myJobArgsTab of myJobArgs;
insert into myJobArgsTab
select myJobArgs (
'myJob', 'chainStep'||rownum, 'arg char '||rownum, date'2018-07-01'+(rownum-1))
from xmlTable ('1 to 3');
Создадим программу и цепочку выполненения, которая будет запускать эту программу в каждом звене: begin
sys.dbms_scheduler.create_program (
program_name=>'myJobProg',
program_type=>'stored_procedure',
program_action=>'myJobProc',
number_of_arguments=>2,
enabled=>false,
comments=>'test job')
;
dbms_scheduler.define_metadata_argument (
program_name=>'myJobProg',
metadata_attribute=>'job_name',
argument_position=>1
);
dbms_scheduler.define_metadata_argument (
program_name=>'myJobProg',
metadata_attribute=>'job_subname',
argument_position=>2
);
sys.dbms_scheduler.enable ('myJobProg');
-- create chain/steps
dbms_scheduler.create_chain ('myJobChain');
dbms_scheduler.define_chain_step ('myJobChain', 'chainStep1', 'myJobProg');
dbms_scheduler.define_chain_step ('myJobChain', 'chainStep2', 'myJobProg');
dbms_scheduler.define_chain_step ('myJobChain', 'chainStep3', 'myJobProg');
-- rules
dbms_scheduler.define_chain_rule ('myJobChain', condition=>'true', action=>'start chainStep1');
dbms_scheduler.define_chain_rule ('myJobChain', condition=>'chainStep1 completed', action=>'start chainStep2');
dbms_scheduler.define_chain_rule ('myJobChain', condition=>'chainStep2 completed', action=>'start chainStep3');
dbms_scheduler.define_chain_rule ('myJobChain', condition=>'chainStep3 completed', action=>'end');
dbms_scheduler.enable ('myJobChain');
end;
/
Тест процедура: create or replace procedure myJobProc (jobName varchar2, jobStepName varchar2) is
rowid_ rowid;
args myJobArgs;
begin
begin
select value (t) into args
from myJobargsTab t
where upper (t.jobName) = myJobProc.jobName
and upper (t.jobStepName) = myJobProc.jobStepName
for update
;
exception when others then
dbms_output.put_line ('ERROR: '||jobName||'.'||JobStepName||': sqlerrm:'||sqlerrm);
end;
insert into myJobInfo (beg, info) values (
systimestamp, jobName||'.'||JobStepName||': args='||args.argChar||'/'||to_char (args.argDate,'yyyy-mm-dd'))
returning rowid into rowid_
;
sys.dbms_lock.sleep (3);
update myJobInfo set end=systimestamp where rowid=rowid_;
end;
/
Запустим всю цепочку и посмотрим, что получилось: exec dbms_scheduler.run_chain (chain_name=>'myJobChain', start_steps=>null, job_name=>'myJob'); select * from myJobInfo order by beg desc; BEG END INFO
------------ ------------ ----------------------------------------------------------------
10:52:24.246 10:52:27.246 MYJOB.CHAINSTEP3: args=arg char 3/2018-07-03
10:52:21.202 10:52:24.202 MYJOB.CHAINSTEP2: args=arg char 2/2018-07-02
10:52:18.154 10:52:21.154 MYJOB.CHAINSTEP1: args=arg char 1/2018-07-01
Для дальнейшей информации читаем оф. документацию тут и тут
Какая разница между двумя модулями в Python? Для примера я взял pickle но есть и другие модули подобного вида, что лучше и когда применять, дайте совет
Ответ
Модуль pickle сразу импортирует _pickle , если есть такая возможность. _pickle это c оптимизированная версия pickle Из исходников модуля pickle # Use the faster _pickle if possible
try:
from _pickle import (
PickleError,
PicklingError,
UnpicklingError,
Pickler,
Unpickler,
dump,
dumps,
load,
loads
)
except ImportError:
Pickler, Unpickler = _Pickler, _Unpickler
dump, dumps, load, loads = _dump, _dumps, _load, _loads
В Python 2 _pickle была также известна как cPickle Источник
На странице, в которой ввожу данные, кодировка текста "< meta charset="utf-8>". Ввел строку "Главная"
Вывод на другой странице выглядит так:
В БД кодировка - utf8_general_ci, а запись этих строк выглядит вот так:
Ответ
Скрипт, который пишет в БД, не установлена кодировка обмена с mysql. В итоге скрипт пишет в БД в кодировке по умолчанию (скорее всего Latin). Поскольку и читает он в этой же кодировке, то на сайте все отображается как надо, а вот в phpMyAdmin, настроенном на utf8, вы видите "кракозябры". В скрипте, после соединения с БД надо выполнить запрос SET NAMES utf8
чтобы установить нужную кодировку обмена с БД
Tickers.All(); class Tickers : Eloquent
{ } class Eloquent
{
public static void All()
{
Console.WriteLine("Класс из которого вызывали меня");
}
}
Хочу в классе Eloquent получить название класса Tickers. Подскажите пожалуйста)
Ответ
Статические методы привязаны к определенному типу и не наследуются. В вашем случае Tickers.All() на самом деле скомпилится в Eloquent.All(), поэтому в рантайме не будет даже упоминания о Tickers Чтобы реализовать вашу задумку, нужно немного подшаманить: Вариант 1 class Tickers : Eloquent
{
public static new void All() => Eloquent.All();
} class Eloquent
{
public static void All()
{
var stacktrace = new StackTrace();
var prevframe = stacktrace.GetFrame(1);
var method = prevframe.GetMethod(); Console.WriteLine($"Вызывающий класс: {method.ReflectedType.Name}");
}
}
Либо, как прокомментировал @Grundy, посмотреть еще один способ. Если коротко, то: Вариант 2 class Tickers : Eloquent
{
} class Eloquent where T: Eloquent
{
public static void All()
{
Console.WriteLine($"Вызывающий класс: {typeof(T).Name}");
}
}
Есть таблица в Postgres, как на картинке. Формат данных в before и after - JSON.
Необходимо сравнить данные из before и after внутри zone_limitation. Основная проблема заключается в том, что данные могут иметь разную сортировку, а при разной сортировке такие JSON-ячейки будут восприниматься, как разные, даже если будут иметь одинаковые цифры внутри.
Ответ
в postgresql есть операторы @> и <@ для jsonb эти операторы проверяют структурного вхождение одного jsonb в другой (не взирая на последовательность ключей), т.о. если вам нужно проверить эквивалентность, то можно использовать комбинацию этих операторов, например: with t as (
select
"id",
"before"#>'{"custom_targeting","include","zone_limitation"}' as "b",
"after"#>'{"custom_targeting","include","zone_limitation"}' as "a"
from "test"
)
select
t.id "id",
(t.a @> t.b and t.a <@ t.b)::boolean "Checker"
from t
order by 1
*данный ответ базируется на dbfiddle от 2SRTVF, см. оригинальный ответ: https://ru.stackoverflow.com/a/858064/265453
Ниже представлен HTTP-запрос. Мне нужно извлечь из него данные - массив с ключами cells и distance. curl http://localhost:80/problem2.php -X POST -H Content-Type:application/json --data-binary "{'cells': [4,8,11,18,19], 'distance': 2}"
Но ничего не выходит, так как данные считываются не верно. Ниже - считывание данных. $data = json_decode(file_get_contents('php://input'));
Известно, что file_get_contents('php://input') точно получает данный массив. Почему json_decode() может не рабоать?
Ответ
JSON строго регламентирует использование двойных кавычек:
--data-binary '{"cells": [4,8,11,18,19], "distance": 2}'
var_dump(json_decode('{"cells": [4,8,11,18,19], "distance": 2}'));
Fiddle
Вот у меня есть код: class BaseInput{
constructor(value){
this.makeButtonVisible = null;
this.makeButtonVisible = function(){
alert(1234);
};
this.makeButtonInvisible = null; this._input = document.createElement('input');
this._input.type = 'text';
this._input.value = value;
this._input.dataset.value = value; this._input.oninput = function(){
if (this.value != this.dataset.value)
BaseInput.makeButtonVisible();
else
alert(321);
} document.querySelector('.container').appendChild(this._input);
}
}
в this._input.oninput я добавляю функцию, которая должна обратиться к методам makeButtonVisible или makeButtonInvisible этого объекта
Есть страница A и страница Б. Как при плохом качестве подключения пользователю показывать ProgressBar. Подчеркиваю что это событие должно происходить именно при ПЛОХОМ качестве подключения к сети ! Спасибо!!!
Ответ
А как вы собираетесь узнать, что у него плохое качество? Вообще вас спасет Loader, он плюс минус для такого и нужен. Чем быстрее страница будет грузиться, тем меньше по времени он будет, ну и плюс современно. P.S. Как вариант, плохое качество можно задетектить с помощью JS смотреть за сколько секунд страница A грузится, если больше определенного времени - ставим куку (временную), и тогда при запросе страницы Б, смотрим наличие этой куки, если есть, то выкидываем лоадер.
Подскажите линукс дистрибутив (или что удалить лишнего), чтобы было возможно запускать только java команды? Мне не нужен ни GUI, ни apt-get, ничего такого. Как я понял, нужно оставить лишь папку bin, в которой сидит bash и его друзья. я прав?
Ответ
Соберите свой, если есть часов 40-60 свободного времени. Linux From Scratch например дает пошаговые инструкцию. На сайте Oracle есть исходники, можете скрафтить сами. Минимальные дистры:
http://www.linuxfromscratch.org/
https://www.archlinux.org/
http://puppylinux.com/
Исходники OpenJDK
http://openjdk.java.net/
Я обычно ставлю тарбол от Oracle, там все в одном архиве - целевой дистр Ubuntu 16.04: гоняется 2 кастомных приложения, сами приложения больше, чем весь дистр.
Создал XML файл с помощью класса XDocument. Вывожу готовую Xml в Консоль, но не вижу там xml заголовка в начале файла. Если его сохранить на диск, то заголовок присутствует. Почему так происходит? И как можно его туда добавить? XDocument xdoc = new XDocument( new XDeclaration("1.0", "Windows-1251","yes"),
new XElement("Product",
new XElement ("prequest",
new XElement("req",
new XElement("AddressReq",
new XElement ("street","Горького"),
new XElement ("houseNumber","1"),
new XElement("apartment", "38"),
new XElement("city", "Магадан"),
new XElement("postal", "685000"),
new XElement("addressType", "1")),
new XElement("AddressReq",
new XElement("street", "Горького"),
new XElement("houseNumber", "1"),
new XElement("apartment", "38"),
new XElement("city", "Магадан"),
new XElement("postal", "685000"),
new XElement("addressType", "1")),
new XElement("IdReq",
new XElement("idNum", "273"),
new XElement("idType","21"),
new XElement("seriesNumber", "64"),
new XElement("issueCountry", "г. Магадан"),
new XElement("issueDate", "2006-03-18"),
new XElement("issueAuthority", "ОВД")
),
new XElement("IdReq",
new XElement("idNum", "1"),
new XElement("idType", "32")
),
new XElement("InquiryReq",
new XElement("ConsentReq",
new XElement("consentFlag", "Y"),
new XElement("consentDate", "2016-01-20"),
new XElement("consentExpireDate", "2021-10-21"),
new XElement("consentPurpose", "4"),
new XElement("otherConsentPurpose", "Job pre-screening"),
new XElement("reportUser", "DG Human Resources Incorporated"),
new XElement("liability", "Y")
),
new XElement("inqPurpose", "01"),
new XElement("inqAmount", "10000"),
new XElement("currencyCode", "usd")
),
new XElement("PersonReq",
new XElement("name1", "К"),
new XElement("first", "Г"),
new XElement("paternal", "Г"),
new XElement("gender", "1"),
new XElement("birthDt", "1900-00-00"),
new XElement("placeOfBirth", "Москва")
),
new XElement("RequestorReq",
new XElement("MemberCode", "V"),
new XElement("UserID", "V"),
new XElement("Password", "1")
),
new XElement("RefReq", new XElement("product", "CHST")
),
new XElement("IOType","B2B"),
new XElement("OutputFormat", "xml"),
new XElement("lang", "ru")
))
))
Вывод в консоль : xdoc.Save("C:\\file.xml"); //В сохраненном файле xml есть заголовок
byte[] byteArray = Encoding.GetEncoding(1251).GetBytes(xdoc.ToString());
BinaryWriter write = new BinaryWriter(File.Open("C:\\file.dat", FileMode.OpenOrCreate));
write.Write(byteArray); //а вот в бинарном файле нет. Console.WriteLine(xdoc); //Если вывести сам xdoc то тут тоже нет заголовка.
Console.ReadKey();
Ответ
Метод ToString у класса XDocument не выводит заголовок xml. Поэтому его нет в бинарном файле. Когда вы пишете Console.WriteLine(xdoc) - тут тоже вызывается ToString Хотите получить заголовок в консоли, используйте xdoc.Save(Console.Out);
Не пугайтесь, что encoding выведется другой. Кодировка будет такой, какую поддерживает консоль.
1) Подскажите, как реализовать такую диаграмму, которая бы рабоатла вместе с календарем. Как нарисовать это все. 2) Внизу есть список из radioButton и поверх них зеленная линия вертикальная. Как сделать эту линию в RecyclerView?
Ответ
Пожалуй начнем с простой, второй части: Нижняя часть экрана - это RecyclerView. RadioButton находиться всегда в одном месте в Item/ячейке/поле этого RecyclerView. Тогда, поверх RecyclerView, вы проводите прямую: FrameLayout шириной в 1 пиксель, нужного цвета таким образом, чтобы он оказался поверх RadioButtons. Высоту RecyclerView ставите по контенту, чтобы прямая не уходила в никуда (либо приделываете эту маленькую палочку непосредственно к RadioButton в самом Item, получается эдакая прямоугольная башенка) Верхняя часть сложнее. Так или иначе придется копаться в канвасе и писать собственный фрагмент с диаграммой. Вы можете попробовать найти схожую либу с открытым исходным кодом и "позваимствовать" код оттуда (android arsenal вам в помощь). График вы оформляете в виде фрагмента, где месяцы - это TabLayout + ViewPager Как-то так.
При обучении сети необходимо заранее указывать количество эпох обучения. При этом не обязательно, что сеть с каждой эпохой будет становиться лучше. Можно ли организовать обучение сети таким образом, чтобы после каждой эпохи сравнивать получившуюся сеть с лучшей? Чтобы после того, как пройдет заданное количество эпох, была получена лучшая сеть за все время обучения, а не сеть после обучения на заданное количество эпох.
Ответ
Вы можете воспользоваться callbacks для сохранения лучшей модели и для ранней остановки (чтобы избежать бесполезных вычислений и ускорить время обучения модели): from keras.callbacks import EarlyStopping, ModelCheckpoint early_stop = EarlyStopping(monitor='val_acc', min_delta=0.0001,
patience=5, verbose=1, mode='auto')
chkpt = ModelCheckpoint(model_filename,
monitor='val_loss',
verbose=1,
save_best_only=True,
mode='auto')
callbacks = [early_stop, chkpt] hist = model.fit(x_train, y_train,
batch_size=Batch_size, epochs=Epochs,
validation_data=(x_val, y_val),
callbacks=callbacks)
При вводе, например, десятого элемента и попытке сменить его значение, меняет 3ий элемент, при попытке сменить первый элемент может сменить 4ый, выходит какой-то рандом, в чем проблема? int &change(int i);
int vals[10];
int main(){ int ch, newval;
cout << "Enter your array.." << endl;
for(int j = 0;j<10; j++) cin >> vals[j]; cout << " " <<"Choose element which you want to change.. ";
cin >> ch;
cout << "Enter the new value for this element.. ";
cin >> newval;
newval = change(vals[ch-1]);
cout << endl;
for (int i=0; i<10; i++) cout << vals[i] <<" "; // вывод массива
return 0;
} int &change(int k){ return vals[k];
}
Ответ
Передавайте в функцию индекс элемента, а не значение из массива: change(ch-1) = newval;
Допустим есть функция, которая возвращает случайную цифру: function getNumber()
{
$Numbers = '1234567890';
$NumbersSize = strlen($Numbers) - 1;
$getNumber = $Numbers[rand(0, $NumbersSize)];
return $getNumber;
}
Как заставить ее возвращать только нужную мне цифру, с помощью цикла?
Ответ
$getNumber = $Numbers[rand(0, $NumbersSize)];
while($getNumber != $nuzhnajaCifra)
$getNumber = $Numbers[rand(0, $NumbersSize)];
return $getNumber;
Но не проще ли без цикла: return $nuzhnajaCifra;
Вот столкнулся с такой проблемой что необходимо сделать скроллбар именно не активным т.к. при скрытии скроллбара сайт разъезжается.
И в целом не вижу смысла делать всем элементам (боди и прочим стики элементам падинги). Вот идеальный пример того что хочу это на сайте apple.com если кликнуть по поиску, то скроллбар как бы остаётся и из него только пропадает сам бегунок и получается аналогичный эффект как при overflow:hidden, но при этом сайт не дергается на эти самые 10/13/16 пикселей. Попытался посмотреть как у них это реализовано, но понять не смог... Возможно js или еще как-то...
В гугле искал ничего толкового не смог найти, все советы просто скрыть скроллбар и всё.
Объясните пожалуйста, почему getSupportFragmentManager().findFragmentById(R.id.fragment_container) возвращает null если в классе SingleFragmentActivity он добавляется в FragmentManager?
public class MyFragment extends Fragment {
}
public abstract class SingleFragmentActivity extends AppCompatActivity {
FragmentManager fm= getSupportFragmentManager();
protected abstract Fragment createFragment();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragment);
Fragment fragment = fm.findFragmentById(R.id.fragment_container);
if (fragment == null) {
fragment = createFragment();
fm.beginTransaction()
.add(R.id.fragment_container, fragment)
.commit();
}
}
}
public class MyActivity extends SingleFragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Возвращает null
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragment_container);
}
@Override
protected Fragment createFragment() {
return new MyFragment();
}
}
Ответ
Вызов commit() не выполняет транзакцию немедленно, а ставит в очередь UI-потока.
Поэтому следующий за ним вызов findFragmentById выполняется раньше, чем фрагмент будет добавлен.
Вместо этого можно завершить транзакцию синхронным методом commitNow() - тогда всё выполнится по порядку.
Для скрипта в Adobe Photoshop, есть диалоговое окно с элементами выбора и управления: var dlg = new Window('dialog{text: "Выбор размеров", bounds: [' + fBounds(150,200,370,150) + '], \
panel_s: Panel{text: "Стандартные:", bounds: [' + fBounds(5,5,203,85) + '], \
checkbox_16: Checkbox{bounds: [' + fBounds(5,13,55,14) + '], text: "16 x 16"}, \
checkbox_24: Checkbox{bounds: [' + fBounds(5,33,55,14) + '], text: "24 x 24"}, \
checkbox_32: Checkbox{bounds: [' + fBounds(5,53,55,14) + '], text: "32 x 32"}, \
checkbox_48: Checkbox{bounds: [' + fBounds(67,13,55,14) + '], text: "48 x 48"}, \
checkbox_64: Checkbox{bounds: [' + fBounds(67,33,55,14) + '], text: "64 x 64"}, \
checkbox_96: Checkbox{bounds: [' + fBounds(67,53,55,14) + '], text: "96 x 96"}, \
checkbox_128: Checkbox{bounds: [' + fBounds(129,13,65,14) + '], text: "128 x 128"}, \
checkbox_256: Checkbox{bounds: [' + fBounds(129,33,65,14) + '], text: "256 x 256"}, \
checkbox_512: Checkbox{bounds: [' + fBounds(129,53,65,14) + '], text: "512 x 512"} \
}, \
panel_o: Panel{text: "Другие:", bounds: [' + fBounds(206,5,69,64) + '],\
checkbox_19: Checkbox{bounds: [' + fBounds(5,13,55,14) + '], text: "19 x 19"}, \
checkbox_38: Checkbox{bounds: [' + fBounds(5,33,55,14) + '], text: "38 x 38"} \
}, \
panel_u: Panel{text: "Свои:", bounds: [' + fBounds(273,5,92,85) + '],\
checkbox_u1: Checkbox{bounds: [' + fBounds(5,13,14,14) + ']}, \
static_u1: StaticText{bounds: [' + fBounds(21,13,31,14) + '], text: ". . . x", justify: "right"}, \
edittext_u1: EditText{bounds: [' + fBounds(53,11,30,19) + '], text: ". . .", properties: {multiline: false}}, \
\
checkbox_u2: Checkbox{bounds: [' + fBounds(5,33,14,14) + ']}, \
static_u2: StaticText{bounds: [' + fBounds(21,33,31,14) + '], text: ". . . x", justify: "right"}, \
edittext_u2: EditText{bounds: [' + fBounds(53,31,30,19) + '], text: ". . .", properties: {multiline: false}}, \
\
checkbox_u3: Checkbox{bounds: [' + fBounds(5,53,14,14) + ']}, \
static_u3: StaticText{bounds: [' + fBounds(21,53,31,14) + '], text: ". . . x", justify: "right"}, \
edittext_u3: EditText{bounds: [' + fBounds(53,51,30,19) + '], text: ". . .", properties: {multiline: false}} \
}, \
button_all: Button{bounds: [' + fBounds(208,70,64,19) + '], text: "Все"}, \
static_save: StaticText{bounds: [' + fBounds(5,99,75,14) + '], text: "Сохранить в:"}, \
drop_save: DropDownList{bounds: [' + fBounds(78,95,287,23) + '], properties: {items: ["папку рядом с исходным файлом", "-", "Выбрать папку..."]}, helpTip:"Ooops!!!"}, \
progress_save: Progressbar{bounds: [' + fBounds(0,0,370,4) + '], value:50}, \
button_run: Button{bounds: [' + fBounds(4,122,70,22) + '], text: "Создать"} \
};'
); // -- Выбор всех значений dlg.show();
Есть обработчик кнопки, для выбора всех чекбоксов: // -- Выбор всех значений
dlg.button_all.addEventListener('click', function() { alert(dlg.panel_s.children + ' ' + dlg.panel_s.children.length);
// Коллекция (9 элементов) и количество (9) отображаются верно alert(dlg.panel_o.children + ' ' + dlg.panel_o.children.length);
// Коллекция (2 элемента) и количество (2) отображаются верно // Объединяем обе коллекции и три отдельных элемента
var aPanel = [].concat(
dlg.panel_s.children,
dlg.panel_o.children,
dlg.panel_u.checkbox_u1,
dlg.panel_u.checkbox_u2,
dlg.panel_u.checkbox_u3
); alert(aPanel + ' ' + aPanel.length);
// Массив отображается верно (14 элементов), но количество не совпадает (5) !
});
Из комментариев в коде обработчика видно, где возникает проблема, и вопрос следующий...Метод Array.prototype.concat(), согласно документации, должен объединять массивы, раскрывая их до первого уровня вложенности. Собственно, так и происходит, если верить последнему всплывающему окну (см. код обработчика) - там отображаются все элементы в порядке добавления.Но, при обращении к aPanel[0], возвращается не первый элемент (checkbox_16), а вся коллекция dlg.panel_s.children . Соответственно при этом, длина массива aPanel составляет 5, а добраться до нужного элемента можно только указав вложенность в коллекции, т.е. aPanel[0][0] .Это баг или хитрая логика? И как правильно объединить массивы с помощью concat() ?
Ответ
Поправочка Действительно, согласно справке MDN
Метод concat создаёт новый массив, состоящий из элементов в объекте,
на котором он был вызван, за которыми по порядку следуют, для каждого
аргумента, все его элементы (если аргумент является массивом), либо
сам аргумент (если он массивом не является)
Только вот про первый уровень вложенности, как видите, тут ни слова.Вот Вам наглядный пример:
let x = [].concat(1, 2, [3, 4], [5, 6, [7, 8]]);
console.log(x); // Выведем полученный массив
console.log(x.length); // Длина равняется не 8, как если бы все раскрывалось
// до первого уровня вложенности, а 7!
console.log(x[6]); // 6-ой элемент является массивом
Однако это не отменяет Вашей проблемы, так как в Вашем случае, если бы элементы dlg.{foo}.children были массивами, то их разворачивание все равно бы произошло
Так в чем же дело? Не буду Вас томить и наконец скажу, в чем же проблема. Еще раз обратите внимание на строчку:
если аргумент является массивом
К чему я клоню? Указанные Вами элементы не являются массивами! Да, они являются коллекциями и подобны массивам, но все же спецификация строга. Давайте посмотрим, как метод concat ведет себя с объектом arguments, который, как и Ваши элементы, является по сути коллекцией, но не массивом:
function test() {
console.log(Array.isArray(arguments)); // false
return [].concat(arguments, arguments);
}
console.log(test(1, 2, 3).toString()); // [object Arguments], [object Arguments]
Как видите, concat не стал разбираться, коллекция ли это или обычный объект. Для него важно лишь то, что данная конструкция не является массивом P.S. - чтобы иметь возможность проверять, является ли объект массивом или нет, советую посмотреть в сторону функции Array.isArray()
Что делать? Лучшим вариантом будет не полениться и все добавить руками: var aPanel = [];
for (let i = 0; i < dlg.panel_s.children.length; i++)
aPanel.push(dlg.panel_s.children[i]);
for (let i = 0; i < dlg.panel_o.children.length; i++)
aPanel.push(dlg.panel_o.children[i]);
aPanel.push(dlg.panel_u.checkbox_u1, dlg.panel_u.checkbox_u2, dlg.panel_u.checkbox_u3);
Другой вариант Можете определить свой метод на уровне прототипа, который как раз и будет разворачивать и массивы, и коллекции до первого уровня:
Array.prototype.fullConcat = function() {
const exclude = ["string"]; // Пусть строка и является коллекцией, но мы хотим считать ее цельным объектом
function getElements(item) { // Рекурсивно получим все элементы внутри заданного (если таковые есть)
let result = [];
if (item.length === undefined || exclude.includes(typeof item))
result.push(item);
else {
for (let i = 0; i < item.length; i++) {
let add = getElements(item[i]);
for (let j = 0; j < add.length; j++)
result.push(add[j]);
}
}
return result;
}
let concated = [];
for (let i = 0; i < arguments.length; i++) { // Начнем объединение
let item = arguments[i];
if (item.length === undefined || exclude.includes(typeof item))
concated.push(item);
else {
for (let i = 0; i < item.length; i++) {
let add = getElements(item[i]);
for (let j = 0; j < add.length; j++)
concated.push(add[j]);
}
}
}
// Не забудем и про контекст this, который может оказаться совсем не пустым
return this.length == 0 ? concated : [].fullConcat(this, concated);
};
function testArguments() {
return [].fullConcat(arguments, arguments);
}
// Проверим, как метод расправится со вложенностью
console.log([1, 2, 3].fullConcat([4], [5, 6, [7, 8, [9, 10]]], "hello", "world")); // 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, "hello", "world"
// Проверим, как метод расправится с коллекцией в лице arguments
console.log(testArguments(1, 2, 3, [4, 5])); // 1, 2, 3, 4, 5, 1, 2, 3, 4, 5
UPD: Большое спасибо @Grundy за то, что обратил мое внимание на следующий момент: Давайте же глянем не справку MDN, а на спецификацию ECMAScript. Обратим внимание на строчки:
Repeat, while items is not empty
a. Remove the first element from items and let E be the value of the element.
b. Let spreadable be ? IsConcatSpreadable(E)
c. If spreadable is true, then // copy items from within the object
d. Else: // copy the object
Или на русском:
Повторять, пока items не пуст
a. Удалить первый элемент из items, присвоить E значение элемента.
b. Присвоить spreadable значение IsConcatSpreadable (E).
c. Если spreadable является true, тогда // копировать элементы изнутри объекта
d. Иначе: // копировать сам объект
То есть за то, будет ли элемент добавлен к результирующему массиву в явном виде, или же он будет предварительно развернут как коллекция, отвечает результат выполнения некой функции IsConcatSpreadable(O). Давайте же взглянем, что это и с чем ее едят:
If Type(O) is not Object, return false
Let spreadable be ? Get(O, @@isConcatSpreadable)
If spreadable is not undefined, return ToBoolean(spreadable)
Return ? IsArray(O).
Или на русском:
Если тип O не Object, вернуть false.
Присвоить spreadable значение свойства @@isConcatSpreadable объекта O.
Если spreadable не undefined, вернуть ToBoolean (spreadable).
Вернуть IsArray(O).
То есть проверка на то, является ли объект массивом, идет в самую последнюю очередь. До этого проверяется, обладает ли объект свойством Symbol.isConcatSpreadable, и если он таковым обладает, то его булевое значение и будет показателем того, будет ли он раскрываться при concat. Давайте теперь применим это на практике:
// Создадим собственную коллекцию
var userCollection = {
0: 'a', 1: 'b', 2: 'c', length: 3
};
// Убедимся, что она не является массивом
console.log(Array.isArray(userCollection)); // false
// Посмотрим, что вернет нам concat
console.log([].concat(userCollection, userCollection)); // Array [ Object(3), Object(3) ]
// Теперь маленькая хитрость:
// Установим внутреннее свойство, отвечающее
// за результат IsConcatSpreadable(O), равным true
userCollection[Symbol.isConcatSpreadable] = true;
// Посмотрим, что теперь вернет нам concat
console.log([].concat(userCollection, userCollection)); // Array [ "a", "b", "c", "a", "b", "c" ]
// Или же сразу создадим коллекцию с указанным свойством:
// Создадим собственную коллекцию
var userCollection_1 = {
0: 'a', 1: 'b', 2: 'c', length: 3, [Symbol.isConcatSpreadable]: true
};
// Посмотрим, что вернет нам concat
console.log([].concat(userCollection_1, userCollection_1)); // Array [ "a", "b", "c", "a", "b", "c" ]
Работает как часы. Давайте для чистоты эксперимента проверим это на существующем перечисляемом типе. Вспомним опять же про наш arguments
// arguments не указан, как spreadable
function nonSpreadable() {
return [].concat(arguments, arguments);
}
// arguments указан, как spreadable
function spreadable() {
arguments[Symbol.isConcatSpreadable] = true;
return [].concat(arguments, arguments);
}
// Какой же массив вернется при объединении 2-х arguments?
console.log(nonSpreadable(1, 2)); // Array [ Arguments, Arguments ]
// А теперь?)
console.log(spreadable(1, 2)); // Array [ 1, 2, 1, 2 ]
console.log(spreadable(1, 2, 3)); // Array [ 1, 2, 3, 1, 2, 3 ]
Как видите, нам удалось с помощью concat объединить внутренние значения arguments в массив Для очистки совести напомню: лезть таким вот образом во внутренние свойства объекта, изменяя логику его работы, - неправильно и кощунственно! Почему? Давайте представим ситуацию: Вы видите массив. Как он должен вести себя с методом concat? Правильно, согласно уже не раз указанной справке он обязан раскрыться при объединении! А что если кто-то с полученным Вами массивом поигрался следующим образом:
// Создадим обычные массивы
var arr_0 = [1, 2];
var arr_1 = [3, 4];
// Убедимся, что это именно массивы, а не что-либо еще
console.log(Array.isArray(arr_0)); // true
console.log(Array.isArray(arr_1)); // true
// Объединим их
var arr_2 = [].concat(arr_0, arr_1);
console.log(arr_2); // Array [ 1, 2, 3, 4 ]
console.log(arr_2.length); // 4, как и полагается
// А теперь сделаем парочку богопротивных действий
arr_0[Symbol.isConcatSpreadable] = arr_1[Symbol.isConcatSpreadable] = false;
// Объединим их снова
var arr_3 = [].concat(arr_0, arr_1);
console.log(arr_3); // Array [ Array(2), Array(2) ]
console.log(arr_3.length); // 2, что-то пошло не так)
Только что мы изменили поведение стандартного типа, что очень и очень неправильно! Так что старайтесь избегать таких вот подходов! Все, совесть очищена, так что можем злоупотреблять дальше :)
Еще один вариант решения Вашей проблемы: На основе манипулирования результатом исполнения IsConcatSpreadable(O) Вашу задачу можно решить таким вот образом: // Колдуем над isConcatSpreadable:
dlg.panel_s.children[Symbol.isConcatSpreadable] = dlg.panel_0.children[Symbol.isConcatSpreadable] = true; // Объединяем обе коллекции и три отдельных элемента
var aPanel = [].concat(
dlg.panel_s.children,
dlg.panel_o.children,
dlg.panel_u.checkbox_u1,
dlg.panel_u.checkbox_u2,
dlg.panel_u.checkbox_u3
);
И живой пример для наглядности:
// Сформируем свои коллекции
var userCollection_0 = {
0: 'a', 1: 'b', 2: 'c', length: 3
};
var userCollection_1 = {
0: 'd', 1: 'e', 2: 'f', 3: 'g', length: 4
};
// Колдуем над isConcatSpreadable
userCollection_0[Symbol.isConcatSpreadable] = userCollection_1[Symbol.isConcatSpreadable] = true;
// Объединяем обе коллекции и три отдельных элемента
var aPanel = [].concat(
userCollection_0,
userCollection_1,
'h',
'i',
'j'
);
// Посмотрим, что внутри
console.log(aPanel); // Array [ "a", "b", "c", "d", "e", "f", "g", "h", "i", "j" ]
// Убедимся, что длина также совпадает
console.log(aPanel.length); // 10 из 10)
Надеюсь, мой ответ помог Вам в разрешении проблемы! Удачи в Ваших начинаниях!
Можно ли над методом рест-контроллера ставить аннотацию @Transactional?
Будут ли проблемы, если одновременно по этому URL одновременно будут пытаться получить данные несколько клиентов?
Ответ
Нельзя, однозначно и бесповоротно. Будут проблемы связанные с обработкой транзакций.
Здесь я укажу некоторые ссылки:
Слой использования @Transactional анотации.
Что лучше всего с @Transactional, вы должны положить его, если у вас
есть доступ к базе данных.
См. «Понимание реализации декларативной транзакции Spring Framework» вы просто аннотируете свои классы аннотацией @Transactional, добавляете в свою конфигурацию строку (``), а
затем ожидаете, что вы поймете, как все это работает.
Какой слой использовать для транзакций и сессии Hibernate
Лучше всего использовать управление транзакциями Spring. Аннотации
@Transactional для использования транзакций. На заводе-изготовителе
используется LocalSessionFactoryBean. Все бобы управляются весной,
поэтому у вас нет забот.
Spring Hibernate - различие между CrudRepository и SessionFactory
Просто вы можете найти описание этих аннотаций на сайте docs Spring.
В ближайшее время, чтобы ответить на ваши вопросы, разница между ними
заключается в том, что они используются для разных целей. @Transactional используется для демаркации кода, участвующего в транзакции. Он помещается на классы и методы. @Repository используется для определения Spring-компонента, поддерживающего транзакции, его также можно использовать в DI.
Они могут использоваться как в одном классе.
void getFiles(const string& inpath, string outpath)
{
string mask = inpath + "\\*";
WIN32_FIND_DATA FindFileData;
HANDLE hf;
hf = FindFirstFile(mask.c_str(), &FindFileData); ofstream output;
output.open(outpath + "\\data.txt", ios_base::app); if (hf != INVALID_HANDLE_VALUE)
{
do
{
if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if (strcmp(FindFileData.cFileName, ".") == 0 ||
strcmp(FindFileData.cFileName, "..") == 0) continue;
getFiles(inpath + "\\" + FindFileData.cFileName, outpath);
}
else
output << inpath << "\\" << FindFileData.cFileName << endl; } while (FindNextFile(hf, &FindFileData) != 0);
FindClose(hf);
} output.close();
}
Есть такая функция, которая ищет файлы в выбранном каталоге и его подкаталогах, а потом записывает пути к файлам в data.txt. А как мне сделать так, чтобы эта функция искала только файлы с определенным расширением, например, .xml?
Ответ
Вызов поиска файлов несколько раз с разными расширениями - неверная концепция. Работа с таблицей файлов (на диске) медленнее, чем обработка строк. Поэтому соберите все расширения в хэш-таблицу, список, массив или даже в одну строку, просканируйте файлы единожды с универсальной маской *. Для каждого найденного файла выделите его расширение и проверьте, есть ли оно в выбранной структуре, хранящей нужные расширения.
Добавил обычную функцию отправки письма: $subject = "Test mail"; $message = "Hello! This is a simple email message."; $from = "registration@MYDOMAIN.RU"; $headers = "From: Info "; mail($to,$subject,$message,$headers); echo "Mail Sent.";
Решил проверить на спам через mail-tester. Он показывает 0/10(даже -2).
Самая основная Ошибка, это: Адрес возврата : webmaster@example.com. Хотя я установил FROM. Ошибка точно не в коде отправки почты.
И так же пишет [SPF] example.com не позволяет Вашему серверу myserverIP использовать webmaster@example.com
Те же самые ошибки наблюдаю, если отправляю на любой почтовый сервер письмо. Например на mail.ru. Потом захожу в сведения письма и вижу снова несовпадения. Как будто я отправляю почту от имени другого домена. Хотя я зарегистрировал адрес почты. Как еще подтвердить, что мой сервер, домен и почта одно целое? Установлен centos на vds. Стоит ispManager.
Настроил на домене все необходимые txt, CNAME, mx записи с yandex
Добавил через pdd.yandex.ru домен и подтвердил его. Создал там почту. Добавил все необходимые spf, DKIM подписи РЕШЕНИЕ
Необходимо установить опцию sendmail_path = /usr/sbin/sendmail -t -i -f mail@domain.com
в php.ini
Ответ
ISPManager использует для PHP тот E-Mail, который прописан для сайта в его настройках в качестве адреса вебмастера. Это делается путём установки параметра PHP sendmail_path в конфигурационных файлах Apache, добавляя в секцию строку вида php_admin_value sendmail_path "/usr/sbin/sendmail -t -i -f webmaster@example.com". Можете попробовать сменить в панели адрес на ваш настоящий. Этот параметр относится к PHP_INI_SYSTEM, так что изменить его можно лишь в системном php.ini или в конфигурационном файле Apache. Также не забудьте про SPF, DKIM и DMARC записи в DNS.
Куда сохраняются приватные свойства созданного объекта? Например у нас есть такой код:
function User() {
var firstName, surname;
this.setFirstName = function(firstNameUser) {
firstName = firstNameUser;
}
this.setSurname = function(surnameUser) {
surname = surnameUser;
}
this.getFullName = function() {
return surname + ' ' + firstName;
}
}
var user1 = new User();
user1.setFirstName('Phillip');
user1.setSurname('Moore');
console.log(user1)
console.log(window.surname)
Мы создаем приватные свойства firstName и surname, но после создания нового объекта через конструктор, этих свойств нет в этом объекте. И в глобальной области видимости этих свойств тоже нет, куда они тогда сохраняются?
Ответ
Они хранятся в замыкании. Вот более просто пример этого механизма function setSecret(secret) {
const mySecret = `My secret: ${secret}`; return function getSecret() {
return mySecret;
}
} const secret1 = setSecret('secret 1');
const secret2 = setSecret('secret 2'); secret1(); // secret 1
secret2(); // secret 2
В данном случае, при каждом вызове функции setSecret, создается локальная область видимости ( об А ), где хранится одна переменная mySecret. В обычном случае после выполнения функции, об А бы уничтожилась и переменная пропала, НО мы возвращаем функцию, которая имеет доступ к созданной об А, поэтому об А сохраняется. В вашем случае механизм тот же: функция возвращает объект, у которого есть методы, использующие область видимости этой функции.
Как получить всё содержимое внутри HTML-тега в lxml, но без самого тега?
Ответ
Встроенного метода вроде бы нет, но нетрудно написать свой. Проблема в том, что простой текст в lxml не является самостоятельным элементом (в отличие от Text Node в браузерах), поэтому нужно не забыть добавить text в начале. from html import escape # Доступно с Python 3.2
import lxml.html def inner_html(elem):
# Текст в самом начале внутри тега
# (не забываем про экранирование!)
result = [escape(elem.text or '')] # Все элементы-потомки
for child in elem.iterchildren():
result.append(lxml.html.tostring(child, encoding='unicode'))
# Текст в конце тега принадлежит последнему элементу-потомку (tail)
# и добавится автоматически # Собираем результат в одну строку
return ''.join(result)
# В примере подставим <br> чтобы проверить экранирование
>>> node = lxml.html.fragment_fromstring(
'
Есть Код: $find = R::findAll('task','NAME LIKE ?', ['%'.$q.'%']);
if($find){ // Если Массив не Пустой
foreach($find as $res){
echo $res['NAME'];
}
}
var_dump($res);
object(RedBeanPHP\OODBBean)#15 (10) { ["properties":protected]=> array(11) { ["ID"]=> string(1) "1" ["NAME"]=> string(127) "Написать 4 положительных комментария в Instagram'e и пролайкать эти 4 поста" ["DESCR"]=> string(224) "Приветствую я начинающий Блогер, веду свой блог в Instagram'e По скольку сейчас развелось очень много недо блогеров, пропиар... " ["AUTHOR"]=> string(24) "Пользователь" ["CATEGORY"]=> string(10) "Клики" ["PRICE"]=> string(4) "7500" ["WATCHS"]=> string(2) "16" ["RATING"]=> string(1) "2" ["COMPLETS"]=> string(2) "11" ["NOT_COMPLETS"]=> string(1) "2" ["CREATE_DATE"]=> string(19) "2018-06-14 09:20:06" } ["__info":protected]=> array(5) { ["type"]=> string(4) "task" ["sys.id"]=> string(2) "id" ["sys.orig"]=> array(11)
Проблема вот в чем:
Я пытаюсь произвести поиск по средством Библиотеки RedBeanPHP методом findAll() все хорошо, поиск сработал но проблема в том что когда я пытаюсь вывыести Элемент массива по Его Ключу(в моем случае это NAME), Ничего не Выводится...
Ответ
Проблема решилась.
Просто прошелся 2 раза циклом foreach и все. foreach ($find as $res){
$res = (array) $res;
foreach($res as $r){
$r = (array) $r;
echo $r['NAME'];
}
Есть датафрейм df. Есть фича feat имеющая три категории cat1, cat2, и немногочисленная Unknown. Я хочу избавиться от Unknown, раскидав ее по cat1 и cat2 так, чтобы она разлетелась по ним пропорционально их доле в датасете. То есть, если изначально было 45% cat1, 40% cat2 и 5% Unknown, то нужно, чтобы Unknown разлетелась в между cat1 и сat2 в соотношении 9/8. В документации и блогах ничего подобного не нашел.
Ответ
Исходный DF: In [67]: %paste
df = pd.DataFrame({'feat':np.random.choice(['cat1','cat2','Unknown'],
size=100,
p=[0.45,0.40,0.15])})
## -- End pasted text -- In [68]: df.feat.value_counts()
Out[68]:
cat1 49
cat2 36
Unknown 15
Name: feat, dtype: int64
Сначала найдем соотношение между cat1 и cat2 In [69]: pct = df.feat.value_counts() / len(df) In [70]: ratio = pct.loc[['cat1','cat2']].min() / pct.loc[['cat1','cat2']].max() In [71]: pct
Out[71]:
cat1 0.49
cat2 0.36
Unknown 0.15
Name: feat, dtype: float64 In [72]: ratio
Out[72]: 0.7346938775510204
теперь заменим строки с Unknown с таким же соотношением: In [74]: df.loc[df['feat']=='Unknown', 'feat'] = \
...: np.random.choice([pct[['cat1','cat2']].idxmax(), pct[['cat1','cat2']].idxmin()],
...: size=df['feat'].eq('Unknown').sum(),
...: p=[ratio, 1-ratio])
...:
...: In [75]: df.feat.value_counts()
Out[75]:
cat1 62
cat2 38
Name: feat, dtype: int64
проверка соотношения после замены значений: In [76]: pct.loc[['cat1','cat2']].min() / pct.loc[['cat1','cat2']].max()
Out[76]: 0.7346938775510204
У меня есть excel файл с 1000 строками, в каждой набор символов из 10 символов.
Мне нужно каждый из них вставить поочередно в поиск, например, яндекса.
Если выдаваемых результатов более одного - как то отметить эту строку, которую поисковик нашел. (потом я уже в ручную поиск повторю с нужной строкой)
По одному результату будет в каждой строке, а я ищу когда 2 и более.
Ответ
Можно написать функцию, возвращающую число результатов поиска. Пример: import re
import requests
from bs4 import BeautifulSoup def get_search_results_no(search_str):
r = requests.get('http://www.google.com/search',
params={'q':f'{search_str}'}
)
if not r.ok:
r.raise_for_status()
soup = BeautifulSoup(r.text, 'lxml')
n = re.sub('\D', '', re.sub('[^\d]*\s(\d.*\d)\s[^\d]*', r'\1',
soup.find('div',{'id':'resultStats'}).text))
if n == '':
return 0
return int(n)
Использование: In [149]: get_search_results_no('MaxU')
Out[149]: 1050000 In [150]: get_search_results_no('Кирилл Вишняков')
Out[150]: 983000
Имеется утилита, которая запускает батники, которые в свою очередь собирают инфу с помощью утилиты wmic и потом с них форматирует отчет на рабочий стол. Программа в общем-то ничего сложного не делает, обычная работа с файлами и текстом, если упростить, но проблема в том, что при чтении файла (в файле точно не UTF-8, word определил кодировку, как Юникод) поэтому геморрой с обработкой информации, с этим я в общем-то справился, вот только на ноутах она выдает дичь, где используется кириллица. К слову к примеру если в строку я записываю кириллицу сам, то всё ок. Проблема только с файлом. Вот 1 из методов. void networkAdapterGet() {
StringBuilder result = new StringBuilder();
try(BufferedReader reader = new BufferedReader(new FileReader(NETWORK_ADAPTER_INFO_PATH));
BufferedWriter writer = new BufferedWriter(new FileWriter(TEMP_RESULT_FILE_PATH, true))) {
line = reader.readLine();
while (line != null){
if (line.length() > 1){
line = trimSpaces(line);
line = networkAdapterProcessing(line);
if (!line.equals("")){
result.append(line);
result.append(lineSeparator);
}
}
line = reader.readLine();
}
writer.write("Сетевые устройства:");
writer.write(lineSeparator);
writer.write(result.toString());
writer.write(lineSeparator);
writer.write(lineSeparator);
} catch (IOException e) {
e.printStackTrace();
}
}
Скорее всего зря повелся наFileReader/Writer и думаю основная проблема, как раз таки в Reader'е. Пошаманил с кодировками на открытии и получил фигу, упало как раз таки из-за несовпадения кодировок, можно конечно перебрать вариантов там пара всего, но хотелось бы узнать можно ли как-то это дело исправить. Это пока единственный мешающий/раздражающий баг на данном этапе разработки утилитки.
Ответ
Нужно писать в той кодировке, которая читается клиентом. Чтобы указать кодировку надо заменить FileWriter на new OutputStreamWriter(new FileOutputStream(TEMP_RESULT_FILE_PATH), StandardCharsets.UTF_8);
если кодировка UTF_8 не подходит, то можно попробовать KOI-8 или CP1251, или другая кодировка, которая поддерживает кирилицу, например CP866
Файл build.gradle выглядит следующим образом: apply plugin: 'com.android.application' android {
compileSdkVersion 27
defaultConfig {
applicationId "com.example.recyclerviewexample"
minSdkVersion 14
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
} dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.0.0-beta01'
implementation 'androidx.recyclerview:recyclerview:1.0.0-beta01'
}
Но в результате сборки ошибки: Information:Gradle tasks [:app:generateDebugSources, :app:generateDebugAndroidTestSources, :app:mockableAndroidJar]
C:\Users\Xu\.gradle\caches\transforms-1\files-1.1\appcompat-1.0.0-beta01.aar\45f296cd7466b0137ad2b0b5868320be es\values-v28\values-v28.xml
Error:(9, 5) error: resource android:attr/dialogCornerRadius not found.
C:\Users\Xu\.gradle\caches\transforms-1\files-1.1\appcompat-1.0.0-beta01.aar\45f296cd7466b0137ad2b0b5868320be es\values\values.xml
Error:(1304, 5) error: resource android:attr/fontVariationSettings not found.
Error:(1304, 5) error: resource android:attr/ttcIndex not found.
D:\Android Projects\RecyclerViewExample\app\build\intermediates\incremental\mergeDebugResources\merged.dir\values-v28\values-v28.xml
Error:(11) error: resource android:attr/dialogCornerRadius not found.
Error:(7) resource android:attr/dialogCornerRadius not found.
Error:(11) resource android:attr/dialogCornerRadius not found.
D:\Android Projects\RecyclerViewExample\app\build\intermediates\incremental\mergeDebugResources\merged.dir\values\values.xml
Error:(231) resource android:attr/fontVariationSettings not found.
Error:(231) resource android:attr/ttcIndex not found.
Error:failed linking references.
Error:java.util.concurrent.ExecutionException: java.util.concurrent.ExecutionException: com.android.tools.aapt2.Aapt2Exception: AAPT2 error: check logs for details
Error:java.util.concurrent.ExecutionException: com.android.tools.aapt2.Aapt2Exception: AAPT2 error: check logs for details
Error:com.android.tools.aapt2.Aapt2Exception: AAPT2 error: check logs for details
Error:Execution failed for task ':app:processDebugResources'.
> Failed to execute aapt
Information:BUILD FAILED in 7s
Information:13 errors
Information:0 warnings
Information:See complete output in console
При этом, если блок dependencies выглядит так: dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'
}
то сборка проходит успешно. Как добавить зависимость androidx в проект? Версия Android Studio - 3.0.1.
Ответ
Согласно доке
New Project If you create a new project using the androidx-packaged
dependencies (as opposed to refactoring an existing project with the
Android Studio tool), your new project needs to target API level 28,
and you will need to add the following lines to your gradle.properties
file:
android.useAndroidX=true
android.enableJetifier=true
требуется выставить targetSdkVersion как минимум 28 и добавить явное разрешение на использование либ из androidx пакета в файле gradle.properties android.useAndroidX=true
android.enableJetifier=true
Всем добрый день! Как правильно составить регулярку, пробовал, но не получается то, что нужно. Есть много текста вида "rwrwerw rewrwr http://www.site1.com rewrwrw rewrewrwe needword rewrewrewrwe fdsfasfafdsa http://www.site2.com fdsafsafdsafsaf rewrewrew rewrewrewrwe fdsfasfafdsa http://www.site3.com fdsafsafdsafsaf rewrewrew" Как можно разбить текст разделителем по слову "http://www.site.com" регуляркой с сохранением содержимого регулярки. Или найти/вернуть куски текста "http://www.site.com fdsfsaf fdsfsaf" включающие http://www.site.com в начале, но исключающие следующий http://www.site.com. Следующий http://www.site.com будет со своим последующим текстом. Перепробовал кучу вариантов, но что-то не получается. Такой вариант вроде подходит ~((?:http|https)://.?)(?=[\s]+).?(?=(?:http|https))~is Но preg_match_all возвращает подстроки с site1 и site2, а блок текста с site3 не возвращает
Есть строка r, из которой надо достать только ФИО человека с помощью регулярных выражений. Максимум что у меня вышло это получить '=Иванов Иван Иванович,'. Как можно дополнить выражение, чтобы получить ФИО без лишних знаков? import re
r = 'CN=Иванов Иван Иванович,OU=0072,OU=007,OU=Users,OU=Departments,DC=contoso,DC=com,DC=ua'
result = re.search(r'=\D+,',r)
print(result)
Ответ
text = 'CN=Иванов Иван Иванович,OU=0072,OU=007,OU=Users,OU=Departments,DC=contoso,DC=com,DC=ua' import re
result = re.search(r'CN=(.+?),', text)
print(result)
print(result.group(1)) # 'Иванов Иван Иванович'
У того текста очень простой формат, можно сгенерировать словарь:
Поддержка ключей для нескольких значений: from collections import defaultdict
key_by_values = defaultdict(list) for x in text.split(','):
k, v = x.split('=')
key_by_values[k].append(v) print(key_by_values['CN']) # ['Иванов Иван Иванович']
print(key_by_values['OU']) # ['0072', '007', 'Users', 'Departments']
Ключ для одного значения: # В одну строку:
key_by_value = dict(x.split('=') for x in text.split(',')) # Или более привычно:
key_by_value = dict() for x in text.split(','):
k, v = x.split('=')
key_by_value[k] = v print(key_by_value['CN']) # 'Иванов Иван Иванович'
print(key_by_value['OU']) # 'Departments'
В bitbucket.org увидел у некоторых issue статус wontfix. Что это за статус?
Ответ
WONTFIX - The problem described is a bug which will never be fixed
(взято с https://en.opensuse.org/Bug_Status_WONTFIX) Это статус для ошибок, которые признаны ошибками, но которые не будут исправляться, в виду различных причин (к примеру, излишней сложности исправления, нецелесообразности и т.п.)
Можете, пожалуйста, подсказать почему в php 5.6.30 данный код: interface IInterface {
public function someMethod();
public function anotherMethod();
}
function classData( ReflectionClass $class )
{
$details = "";
$name = $class->getName(); if ( $class->isInterface() ) {
$details .= "$name -- это интерфейс ";
} if ( $class->isAbstract() ) {
$details .= "$name -- это абстрактный класс ";
}
return $details;
} $class_info = new ReflectionClass('IInterface');
echo classData($class_info);
выводит следующий результат: IInterface -- это интерфейс
IInterface -- это абстрактный класс
Т.е. почему интерфейс определяется как абстрактный класс? Если удалить методы из интерфейса, то отобразится: IInterface -- это интерфейс
Интересный факт: hhvm лишён этого недостатка
Ответ
Существует 2 типа «абстрактности» в php:
explicit - класс, явно определённый, как abstract.
implicit - класс/интерфейс, содержащий абстрактные методы.
Проверить на explicit абстрактность можно так: if ($class->getModifiers() & ReflectionClass::IS_EXPLICIT_ABSTRACT) {
// Перед нами абстрактный класс
}
Демонстрация
Есть задача изменять значение поля input (автоматически делать заглавную букву в начале нового предложения - "чтоб как в word" ) почти получилось при помощи следующей функции
function(){
inputPos = this.selectionStart;
this.value = this.value.replace(/((?:(?:^|[.?!]\s)\s*))(.)/g,
function(m, tail, ch){return tail + ch.toUpperCase()})
this.selectionStart = inputPos;
this.selectionEnd = inputPos;
}
подскажите, как добавить исключение в регулярку, чтобы игнорировались слова длиной в 1 символ (т.к. т.ч. т.е.) и после них буква в слове оставалась строчной Пример ввода:
"любой текст. меняется по onclick в инпуте! текст произвольный, но
нужно игнорировать сокращения т.е. слова длиной в один символ
заканчивающиеся точкой т.к. такова идея. очень лень шифт нажимать...
ну не дичь ли? вот так"
Пример Вывода:
"Любой текст. Меняется по onclick в инпуте! Текст произвольный, но
нужно игнорировать сокращения т.е. слова длиной в один символ
заканчивающиеся точкой т.к. такова идея. Очень лень шифт нажимать...
Ну не дичь ли? Вот так"
Ответ
Я пока лучше ничего не придумал, но вроде работает: /(?<=(^|([а-я]{2,})[!?.]{1,}\s))./
Подробности:
(?<= - начало предпросматриваемой незахватывающей группы
(^|([а-я]{2,}) - условие, по которому мы избавляемся от таких сокращенных слов т.е., т.к. и прочих таких сокращений, где стоит меньше 2 символов а-я
[!?.]{1,} - свои спец. символ, по которым осуществляем поиск в пределах от 1+
) - конец предпросматриваемой группы
- выбираем первую нужную нам букву
var string = 'любой текст. меняется по onclick в инпуте!!! ' +
'текст произвольный... нужно игнорировать сокращения т.е. слова ' +
'длиной в один символ заканчивающиеся точкой т.к. такова идея. ' +
'очень лень шифт нажимать... ну не дичь ли!? вот так';
var value = string.replace(/(?<=(^|([а-я]{2,})[!?.]{1,}\s))./gi, function(ch) {
return ch.toUpperCase();
});
console.log(value);
Есть массив такого вида: Array
(
[0] => Array
(
[date] => 07.08.2018
[name] => Название 1
[desc] => Описание 1.
) [1] => Array
(
[date] => 07.08.2018
[name] => Название 2
[desc] => Описание 2.
) )
Т.е. В массиве массивы в тремя ключами. Как удалять массивы, в которых не заполнен один или более ключей? Т.е. оставлять только те поля, в которых всё заполнено? Например, при таких ситуациях: Array
(
[0] => Array
(
[date] => 07.08.2018
[name] => Название 1
[desc] => Описание 1.
) [1] => Array
(
[date] => 07.08.2018
[name] => Описание 2
[desc] => Описание 2.
) [2] => Array
(
[date] =>
[name] =>
[desc] =>
) )
или Array
(
[0] => Array
(
[date] => 07.08.2018
[name] => Название 1
[desc] => Описание 1.
) [1] => Array
(
[date] => 07.08.2018
[name] => Название 2
[desc] => Описание 2.
) [2] => Array
(
[date] =>
[name] => Описание 3
[desc] =>
) )
Удалить массив с ключом [2]
Как в Laravel использовать подстановку маршрута. Например:$route['category/(:any)/page/(:num)'] = '/category/page/$1/$2';
Ответ
Примерно как-то так: Route::any('category/{id}/page/{page}', 'CategoryController@show')->where('page', '[0-9]+');
И сам контроллер: namespace App\Http\Controllers; use App\User;
use App\Http\Controllers\Controller; class CategoryController extends Controller
{
public function show($id, $page)
{
return;
}
}
Наверное туповатый вопрос, поскольку по логике разархивация должна быть дольше, тем более если есть сжатие. Но всё же, вдруг не всё так просто как кажется. Что будет быстрее, скопировать папку с файлами в 1гб, или же разархивировать архив с точно такими же файлами без сжатия.
Ответ
Думаю все дело в I/O записи, что обычно ниже чем чтения Тесты ~$ du -sh test/
5.2G test/
Прямое копирование: ~$ time cp -R tmp/ test/
real 0m34.953s
user 0m0.084s
sys 0m5.110s
Сжатие, копирование, распаковка: ~$ time { tar cf tmp.tar tmp && mv tmp.tar test/ && tar xf test/tmp.tar -C test/; }
real 1m1.619s
user 0m0.563s
sys 0m12.964s
Копирование уже сжатого каталога: ~$ time cp tmp.tar test/
real 0m26.251s
user 0m0.028s
sys 0m4.557s
Посчитаем колчиество чтения-записи Для архива: ~$ strace cp tmp.tar test/ 2>&1 | grep -c "read\|write"
55259
~$ strace cp tmp.tar test/ 2>&1 | grep -c "write"
27623
Для каталога: ~$ strace cp -R tmp test/ 2>&1 | grep -c "read\|write"
70955
~$ strace cp -R tmp test/ 2>&1 | grep -c "write"
32455
В итоге разница между количеством записей для каталога и пакета вышла 4832, что при копирование на медленный носитель, может значительно увеличить время ожидания. При хорошем CPU имеет смысл паковать все предварительно перед копированием.
00
Есть ли программа, которая бы как компилятор начинала собирать проект и останавливалась после этапа препроцессора? Чтобы оставался чистый код, как если бы его писали без препроцессорных команд. Хотя было бы неплохо, чтобы в итоге он бы разделял фрагменты кода по именам заголовочных файлов.
Ответ
Как минимум в gcc (и, соответственно, в его производных, типа minGW) препроцессор — это отдельная программа, которая назвается cpp: cpp -o yourfile.c.preprocessed yourfile.c Поверьте, один раз прочитав его вывод, вы поймёте, почему фраза "бойтесь своих желаний, они могут сбыться" не лишена смысла :)
Видел как некоторые разработчики удаляют эти строки из layout файла, хотя они появляются изначально по умолчанию. Так что, стоит ли удалять их, раз они не выпоняют важной роли в проекте ?
Ответ
xmlns:app нужен для обозначения кастомных свойст View. xmlns:tools - позволяет среде разработки (в нашем случае, Android Studio) правильно отобразить компоненты для просмотра в режиме дизайна. Подробнее про tools Подробнее про app
Можно ли как-нибудь изменить кастомный макет для Spinner'a после его создания?
Например, у меня есть Spinner, макет которого состоит из TextView и ImageView
наполнение его выглядит так: Spinner spinner = findViewById(R.id.spinner_sorting);
ArrayAdapter spinnerAdapter = new ArrayAdapter(this,
R.layout.spinner_row, R.id.tv_sorting, getResources().getStringArray(R.array.sorting_array));
spinner.setAdapter(spinnerAdapter);
и в итоге Spinner выглядит следующим образом:
А мне хотелось бы изменить каждую вторую ImageView в этом Spinnere. Как это можно сделать?
Ответ
Создала кастомный адаптер для Spinner-a: public class SortingSpinnerAdapter extends ArrayAdapter {
private LayoutInflater inflater;
private Context context;
private String[] data; public SortingSpinnerAdapter(@NonNull Context context, int resource, int textViewResourceId, String[] data) {
super(context, resource, textViewResourceId, data);
inflater = LayoutInflater.from(context);
this.context = context;
this.data = data;
} @Override
public View getView(int position, View convertView, ViewGroup parent) {
return createView(position, convertView, parent);
} @Override
public View getDropDownView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
return createView(position, convertView, parent);
} private View createView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.spinner_row, parent, false);
holder = new ViewHolder();
holder.textView = convertView.findViewById(R.id.tv_sorting);
holder.imageView = convertView.findViewById(R.id.iv_arrow);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
onBindViewHolder(holder, position);
return convertView;
} private void onBindViewHolder(ViewHolder holder, int pos) {
holder.textView.setText(data[pos]);
if (pos % 2 == 0) {
holder.imageView.setImageDrawable(context.getResources().getDrawable(R.drawable.arrow_downward));
} else {
holder.imageView.setImageDrawable(context.getResources().getDrawable(R.drawable.arrow_upward));
}
} static class ViewHolder {
TextView textView;
ImageView imageView;
}
}
В итоге получила именно то, что хотела:
Для примера поставил два блока, чтобы вы увидели, как анимация должна работать и как она работает. Левый блок работает отлично: в зависимости от того, откуда наводят мышью, соответственно от этой стороны срабатывает эффект. В правой стороне есть svg-иконка, которая при наведении выходит поверх синего окна. Если навести, не задевая иконку или текст, можно и не заметить глюк. Но если навести сразу на svg-иконку, то глюк сразу можно увидеть. Немного "поигравшись" указателем внутри svg-иконки, не выходя из рамки svg, можно легко заметить проблему. Ссылка: Codepen . Я считаю, что тут проблема в css Мои попытки: 1. Пытался дать position absolute этому блоку, но тогда все ломалось, и глюк также был 2. Пытался убрать display block из класса icon-close. Это не сработало тоже И много других манипуляций с CSS, но ничего не помогло. Очень прошу помогите.
var nodes = document.querySelectorAll('li'),
_nodes = [].slice.call(nodes, 0);
var getDirection = function (ev, obj) {
var w = obj.offsetWidth,
h = obj.offsetHeight,
x = (ev.pageX - obj.offsetLeft - (w / 2) * (w > h ? (h / w) : 1)),
y = (ev.pageY - obj.offsetTop - (h / 2) * (h > w ? (w / h) : 1)),
d = Math.round( Math.atan2(y, x) / 1.57079633 + 5 ) % 4;
return d;
};
var addClass = function ( ev, obj, state ) {
var direction = getDirection( ev, obj ),
class_suffix = "";
obj.className = "";
switch ( direction ) {
case 0 : class_suffix = '-top'; break;
case 1 : class_suffix = '-right'; break;
case 2 : class_suffix = '-bottom'; break;
case 3 : class_suffix = '-left'; break;
}
obj.classList.add( state + class_suffix );
};
// bind events
_nodes.forEach(function (el) {
el.addEventListener('mouseover', function (ev) {
addClass( ev, this, 'in' );
}, false);
el.addEventListener('mouseout', function (ev) {
addClass( ev, this, 'out' );
}, false);
});
.icon-close {
display: block;
text-align: center;
}
.icon-close svg {
margin-top: calc(70% / 2);
margin-bottom: 20px;
}
.txt {
text-decoration: none;
text-align: center;
display: block;
color: blue;
font-size: 22px;
transition: 0.5s all ease;
position: relative;
z-index: 50;
line-height: 1;
}
.container-inner {
float: left;
width: 100%;
}
.container-inner ul {
margin: 0 auto;
padding: 0;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
}
.container-inner ul:after {
content: "";
display: table;
clear: both;
}
.container-inner ul li {
background-color: rgba(255, 18, 156, 0.9);
-webkit-perspective: 540px;
perspective: 540px;
position: relative;
width: calc(25% - 10px);
height: 290px;
margin: 5px;
padding: 0;
list-style: none;
}
.container-inner ul li:hover svg {
position: relative;
z-index: 5;
}
.container-inner ul li:hover svg path {
fill: white;
}
.container-inner ul li:hover .txt {
color: white;
}
.container-inner ul li .info {
-webkit-transform: rotate3d(1, 0, 0, 90deg);
transform: rotate3d(1, 0, 0, 90deg);
width: 100%;
height: 100%;
padding: 0px 10px;
position: absolute;
top: 0;
left: 0;
border-radius: 4px;
pointer-events: none;
background-color: rgba(26, 88, 156, 0.9);
}
.container-inner ul li .info p {
color: #fff;
}
.in-top .info {
-webkit-transform-origin: 50% 0%;
-ms-transform-origin: 50% 0%;
transform-origin: 50% 0%;
-webkit-animation: in-top 300ms ease 0ms 1 forwards;
animation: in-top 300ms ease 0ms 1 forwards;
}
.in-right .info {
-webkit-transform-origin: 100% 0%;
-ms-transform-origin: 100% 0%;
transform-origin: 100% 0%;
-webkit-animation: in-right 300ms ease 0ms 1 forwards;
animation: in-right 300ms ease 0ms 1 forwards;
}
.in-bottom .info {
-webkit-transform-origin: 50% 100%;
-ms-transform-origin: 50% 100%;
transform-origin: 50% 100%;
-webkit-animation: in-bottom 300ms ease 0ms 1 forwards;
animation: in-bottom 300ms ease 0ms 1 forwards;
}
.in-left .info {
-webkit-transform-origin: 0% 0%;
-ms-transform-origin: 0% 0%;
transform-origin: 0% 0%;
-webkit-animation: in-left 300ms ease 0ms 1 forwards;
animation: in-left 300ms ease 0ms 1 forwards;
}
.out-top .info {
-webkit-transform-origin: 50% 0%;
-ms-transform-origin: 50% 0%;
transform-origin: 50% 0%;
-webkit-animation: out-top 300ms ease 0ms 1 forwards;
animation: out-top 300ms ease 0ms 1 forwards;
}
.out-right .info {
-webkit-transform-origin: 100% 50%;
-ms-transform-origin: 100% 50%;
transform-origin: 100% 50%;
-webkit-animation: out-right 300ms ease 0ms 1 forwards;
animation: out-right 300ms ease 0ms 1 forwards;
}
.out-bottom .info {
-webkit-transform-origin: 50% 100%;
-ms-transform-origin: 50% 100%;
transform-origin: 50% 100%;
-webkit-animation: out-bottom 300ms ease 0ms 1 forwards;
animation: out-bottom 300ms ease 0ms 1 forwards;
}
.out-left .info {
-webkit-transform-origin: 0% 0%;
-ms-transform-origin: 0% 0%;
transform-origin: 0% 0%;
-webkit-animation: out-left 300ms ease 0ms 1 forwards;
animation: out-left 300ms ease 0ms 1 forwards;
}
@-webkit-keyframes in-top {
from {
-webkit-transform: rotate3d(-1, 0, 0, 90deg);
transform: rotate3d(-1, 0, 0, 90deg);
}
to {
-webkit-transform: rotate3d(0, 0, 0, 0deg);
transform: rotate3d(0, 0, 0, 0deg);
}
}
@keyframes in-top {
from {
-webkit-transform: rotate3d(-1, 0, 0, 90deg);
transform: rotate3d(-1, 0, 0, 90deg);
}
to {
-webkit-transform: rotate3d(0, 0, 0, 0deg);
transform: rotate3d(0, 0, 0, 0deg);
}
}
@-webkit-keyframes in-right {
from {
-webkit-transform: rotate3d(0, -1, 0, 90deg);
transform: rotate3d(0, -1, 0, 90deg);
}
to {
-webkit-transform: rotate3d(0, 0, 0, 0deg);
transform: rotate3d(0, 0, 0, 0deg);
}
}
@keyframes in-right {
from {
-webkit-transform: rotate3d(0, -1, 0, 90deg);
transform: rotate3d(0, -1, 0, 90deg);
}
to {
-webkit-transform: rotate3d(0, 0, 0, 0deg);
transform: rotate3d(0, 0, 0, 0deg);
}
}
@-webkit-keyframes in-bottom {
from {
-webkit-transform: rotate3d(1, 0, 0, 90deg);
transform: rotate3d(1, 0, 0, 90deg);
}
to {
-webkit-transform: rotate3d(0, 0, 0, 0deg);
transform: rotate3d(0, 0, 0, 0deg);
}
}
@keyframes in-bottom {
from {
-webkit-transform: rotate3d(1, 0, 0, 90deg);
transform: rotate3d(1, 0, 0, 90deg);
}
to {
-webkit-transform: rotate3d(0, 0, 0, 0deg);
transform: rotate3d(0, 0, 0, 0deg);
}
}
@-webkit-keyframes in-left {
from {
-webkit-transform: rotate3d(0, 1, 0, 90deg);
transform: rotate3d(0, 1, 0, 90deg);
}
to {
-webkit-transform: rotate3d(0, 0, 0, 0deg);
transform: rotate3d(0, 0, 0, 0deg);
}
}
@keyframes in-left {
from {
-webkit-transform: rotate3d(0, 1, 0, 90deg);
transform: rotate3d(0, 1, 0, 90deg);
}
to {
-webkit-transform: rotate3d(0, 0, 0, 0deg);
transform: rotate3d(0, 0, 0, 0deg);
}
}
@-webkit-keyframes out-top {
from {
-webkit-transform: rotate3d(0, 0, 0, 0deg);
transform: rotate3d(0, 0, 0, 0deg);
}
to {
-webkit-transform: rotate3d(-1, 0, 0, 104deg);
transform: rotate3d(-1, 0, 0, 104deg);
}
}
@keyframes out-top {
from {
-webkit-transform: rotate3d(0, 0, 0, 0deg);
transform: rotate3d(0, 0, 0, 0deg);
}
to {
-webkit-transform: rotate3d(-1, 0, 0, 104deg);
transform: rotate3d(-1, 0, 0, 104deg);
}
}
@-webkit-keyframes out-right {
from {
-webkit-transform: rotate3d(0, 0, 0, 0deg);
transform: rotate3d(0, 0, 0, 0deg);
}
to {
-webkit-transform: rotate3d(0, -1, 0, 104deg);
transform: rotate3d(0, -1, 0, 104deg);
}
}
@keyframes out-right {
from {
-webkit-transform: rotate3d(0, 0, 0, 0deg);
transform: rotate3d(0, 0, 0, 0deg);
}
to {
-webkit-transform: rotate3d(0, -1, 0, 104deg);
transform: rotate3d(0, -1, 0, 104deg);
}
}
@-webkit-keyframes out-bottom {
from {
-webkit-transform: rotate3d(0, 0, 0, 0deg);
transform: rotate3d(0, 0, 0, 0deg);
}
to {
-webkit-transform: rotate3d(1, 0, 0, 104deg);
transform: rotate3d(1, 0, 0, 104deg);
}
}
@keyframes out-bottom {
from {
-webkit-transform: rotate3d(0, 0, 0, 0deg);
transform: rotate3d(0, 0, 0, 0deg);
}
to {
-webkit-transform: rotate3d(1, 0, 0, 104deg);
transform: rotate3d(1, 0, 0, 104deg);
}
}
@-webkit-keyframes out-left {
from {
-webkit-transform: rotate3d(0, 0, 0, 0deg);
transform: rotate3d(0, 0, 0, 0deg);
}
to {
-webkit-transform: rotate3d(0, 1, 0, 104deg);
transform: rotate3d(0, 1, 0, 104deg);
}
}
@keyframes out-left {
from {
-webkit-transform: rotate3d(0, 0, 0, 0deg);
transform: rotate3d(0, 0, 0, 0deg);
}
to {
-webkit-transform: rotate3d(0, 1, 0, 104deg);
transform: rotate3d(0, 1, 0, 104deg);
}
}
Pellentesque habitant morbi tristique senectus et netus et
malesuada fames ac turpis egestas. Vestibulum tortor quam,
feugiat vitae, ultricies eget, tempor sit amet, ante.
Donec eu libero sit amet quam egestas semper.
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper.