Страницы

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

среда, 4 марта 2020 г.

Обязательно ли делать ORDER BY для упорядоченных данных [дубликат]

#mysql #sql


        
             
                
                    
                        
                            На этот вопрос уже дан ответ здесь:
                            
                        
                    
                
                        
                            Упорядочивание записей в таблице данных
                                
                                    (1 ответ)
                                
                        
                                Закрыт 2 года назад.
            
                    
К примеру есть таблица users с одним столбцом id

id |
----
1
2
3
4


Я делаю элементарный SELECT

SELECT id FROM users


и получаю данные 1, 2, 3, 4 в том порядке в котором они пронумерованы.  

Собственно вопрос: всегда ли MySQL гарантирует что данные будут получены именно в
том порядке в котором они пронумерованы? Т. е. возможен ли случай когда например результат
будет такой: 1, 3, 2, 4?
Или все же лучше использовать явную сортировку?

SELECT id FROM users ORDER BY id
    


Ответы

Ответ 1



Если вам необходимо получить упорядоченный набор, всегда используйте сортировку. Например, если вставлять строки не по порядку, например так: id | ---- 1 4 2 3 то без сортировки вы их в таком виде и получите. Часто вы будите получать в результате запроса строки в порядке вставки, но даже этого СУБД вам не гарантирует. По этому, всегда когда вам нужен упорядоченный набор данных, указывайте сортировку явно.

Оценить время выполнения программы и вывести в реальном времени процент исполнения программы

#python


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

import os


def scan_dir(path):
    print('[',path,']')

    for file in os.listdir(path):
        file_path = os.path.join(path, file)
        if os.path.isfile(file_path):
            print('\t', file)
        else:
            scan_dir(file_path)

if __name__ == '__main__':
    scan_dir('C:\djangoProjects')

    


Ответы

Ответ 1



Всё просто: разбирить процесс на 2 стадии: Посчитать всё количество файлов в каталоге, который обходите — типа оценка времени. Собственно в цикле где работаете с файлами производить отчет, какой % обработан и сколько осталось — и согласно этому изменяете свой прогресс-бар. Но если вы прям хотите время выводить (приблизительное само собой, которое также может меняться): тоже нужно провести какую-то оценку. Нужно знать общий объем файлов, которые будут участвовать в обходу. И как как размер файлов разный можно, например, посчитать сколько времени уходит на обработку 5% файлов и на основе этого расчитать приблизительное оставшиеся время на обработку.

Ответ 2



Не зная заранее ни количество файлов ни сколько обработка выбранного файла может занять, вы не сможете узнать на ходу сколько осталось времени до конца выполнения программы. Часто хорошим предсказателем времени выполнения является время выполнения прошлого запуска. При первом запуске можно показывать просто абсолютные числа (количество просмотренных директорий, файлов, среднее время на файл). При последующих запусках, можно дополнить сравнением с прошлым, что может позволить оценить "сколько ещё ждать". К примеру, для задачи резервного копирования, если в прошлом запуске было обработано 1000 файлов, в среднем по минуте на каждый, а в текущем запуске вы на 900-ом файле, то можно написать, что оценочно ~90% сделано, осталось ~100 минут. Конечно, оценки будут ошибочными, если у вас вдруг стало 10000 файлов вместо 1000 на прошлом запуске. Если есть желание, то и при первом запуске можно оценить время выполнения. Если время обработки одного файла заметное и уже по одному количеству файлов ясно время выполнения, то можно вхолостую обойти всё дерево директорий как @Alexander Bragin предложил. Это не должно удваивать время на обход, так как OS кэширует информацию о файловой системе обычно (диск на порядки медленнее оперативной памяти как правило). Всё зависит от фактической задачи, какие предположения, которые могут помочь в оценке времени выполнения, являются верными в вашем конкретном случае.

Как добавить текст в SVG?

#css #svg


Есть SVG демка https://codepen.io/anon/pen/gxMJOJ

Все блоки, как положено разделены на группы , но текст описания, размещенный в
  не отображается:


  Заголовок 10
  Текст 10
    



И ещё не нашёл информации как выравнивать текст внутри SVG-блока?
    


Ответы

Ответ 1



Теги ... можно добавлять в любое место svg кода. Это своего рода поясняющий текст, в котором можно разместить, что угодно, от комментарий до ссылок и всё это не будет видно пользователю на дисплее, но поисковики, особенно Google хорошо индексируют содержание в этих тегах. Теги ... выступают в роли тултипа. Наведите курсор на блок и должен появиться текст, который размещен в этих тегах. Тоже индексируется. Текст добавляется в svg c помощью тегов .... Внутри файла SVG позиционирование текста абсолютно при этом указывается координаты X, Y начала текста. Ваш пример я прогнал через SVG оптимизатор для уменьшения кода и лучшего понимания. Заголовок 10 Текст 10 Заголовок 10 Текст 10 Текст 10 Текст 10 Текст 10 Текст 10 Текст 10 Заголовок 11 Текст 11 Заголовок 11 Текст 11 Текст 11 Текст 11 Текст 11 Заголовок 12 Текст 12 Заголовок 12 Текст 12 Текст 12 Текст 12 Текст 12 В svg нет автоматического переноса текста, как в Html поэтому приходится применять относительное позиционирование с помощью тегов .. , которые имеют атрибуты dxи dy относительного смещения текста по координатам. Текст 10 Текст 10 Текст 10 Текст 10 Текст 10 Текст 10 Позиционирование текста с помощью атрибута text-anchor Start middle End

Как убрать во фрейме скролл, но заставить контент прокручиваться

#html


Вот такой код не прокручивает содержимое:







    


Ответы

Ответ 1



В вебките можете удалить его с помощью css: ::-webkit-scrollbar { width:0; }

Как ограничить зону видимости глобальной переменной в многофайловой программе

#c


Нужно, что бы var не был виден в main, но виделся и использовался в других файлах.

Когда было сделано как ниже - работало.

MAIN.c
#include Header.h
foo1();

Header.h
void foo1(void);
void foo2(void);
void foo3(void);

Variables.h
static int var;

Source.c
#include Header.h
#include Variables.h
foo1(){var++;}
foo2(){var++;}
foo3(){var++;}


После изменения как ниже - перестало, при каждом вызове функции var == 0, а вне не
определен.

MAIN.c
#include Header.h
foo1();

Header.h
void foo1(void);
void foo2(void);
void foo3(void);

Variables.h
static int var;

Source1.c
#include Header.h
#include Variables.h
foo1(){var++;}

Source2.c
#include Header.h
#include Variables.h
foo2(){var++;}

Source3.c
#include Header.h
#include Variables.h
foo3(){var++;}

    


Ответы

Ответ 1



А какой смысл в вашем пожелании? Вы хотите использовать в main() свою переменную с именем var или что? Просто смысл глобальной переменной именно в этом - быть видимой везде, во всех файлах. Так что поясните, что именно вы хотите, а то пока что требования у вас противоречивые... Может, можно было бы использовать статическую переменную в функции - например, Variables.h int* getVar(); Variables.c int* getVar() { static int var; return &var; } SourceN.c #include "Header.h" #include "Variables.h" void fooN(){ (*getVar())++; } Но чтобы понять, подходит ли вам это решение - нужно понимать, что вы хотите. Глобальные переменные вообще лучше не использовать... И еще - по первому варианту у вас в main() своя переменная var, в Source - своя. Как и во втором - в каждом файле - своя переменная. Это - не глобальная переменная, она просто видна везде на уровне файла, но в каждом файле она своя.

Структура приложения PHP

#php #phpstorm


Здравствуйте. Хотелось бы попросить совета, как правильно организовать структуру
приложения. Я только учусь разработке на PHP. Не судите строго. 

Задание такое, необходимо создать приложение в котором пользователи могут общаться
между собой. Будет личный кабинет пользователя, и будет админка, где админ может видеть
всех пользователей на сайте.

Не могу представить в голове структуру. На данный момент Вижу только такое: 



По папкам:


auth - Страница авторизации;
profile - Страница с личным кабинетом, куда пользователь попадет после авторизации;
templates - header.php,footer.php и остальные файлы, все они будут, как шаблон сайта
core - предположительно ядро, и через эту папку можно будет войти в админку;
lib - другие функции... 


Вот из этого вопрос, как лучше организовать это. 
    


Ответы

Ответ 1



У меня обычно для несложных приложений с нуля структура, позаимствованная из систем пэкиджей Linux и Windows, некоторый микс: В приложении есть модули Каждый модуль хранится в своей папке (это список папок, а не дерево) В этой папке есть подпапки, например, php, css, js, html, tpl Любое обращение, за исключением запросов к файлам (картинкам), производится только к одному скрипту: index.php, в котором настраивается autoload. Чтобы к index.php нельзя было обратиться напрямую, в файле .htaccess с помощью mod_rewrite задается переменная MODULE c соответствующим значением, например, admin или frontend (это названия модулей), которая будет видна в массиве $_SERVER Усли у заданного модуля есть контроллер, хоторый лежит в файле modulename/php/Ctrl.php, то index.php созздает экземпляр этого контроллера и запускает. Довольно удобно для небольших приложений без фреймворка, поскольку сразу понятно, какой файл где искать, в отличие от структур, в которых кучи однотипных файлов разных модулей свалены в одну папку, что требует еще и наличие установщика модулей.

Ответ 2



Смотрите как это организовано в популярных фреймворках. Например: https://github.com/yiisoft/yii2-app-basic https://github.com/yiisoft/yii2-app-advanced https://github.com/zendframework/ZendSkeletonApplication Да тот же 1С-Битрикс установите - посмотрите структуру как делать не стоит или наоборот стоит (тут на вкус и цвет...) ;) А лучше на основе фреймворка и делать проект. Когда над вашим проектом будут работать другие люди - за самописное решение большого спасибо не скажут. Именованием файлов, стайлгайд, автолоадер и т.д. обратите внимание на http://www.php-fig.org/psr/. Если возникнет вопрос: а что изучать? Смотрите и отталкивайтесь от вакансий - что требуется и что чаще, а также вилку ЗП. И не PHP едины - это главное не забывайте.

Как использовать сопрограммы С++ с Boost.Asio?

#cpp #boost #сопрограмма


Есть прокси-сервер, написанный на асинхронном API Boost.Asio - async_* функции и
коллбеки.

Полный код есть в этом ответе.
Схематично его можно описать так:

Цикл приема входящих соединений, установка соединения с сервером назначения:

void accept_loop() {
   acceptor.async_accept(src_socket, [](auto err) {
     accept_loop();  // повторяем accept

     dst_socket.async_connect(dst_endpoint, [](auto err) {
       proxy_loop(src_socket, dst_socket);
       proxy_loop(dst_socket, src_socket);
     });
  });
}


Цикл передачи данных, по 2 шт. на каждое соединение:

void proxy_loop(socket src, socket dst) {
  async_read(src, buf, [](auto error, auto n) {
    async_write(dst, buf, [](auto error, auto n) {
      proxy_loop(src, dst);  // повторяем read
    });
  });
}


Как переписать этот сервер с использованием сопрограмм С++?
    


Ответы

Ответ 1



В настоящий момент нет стандартного класса Future, который был бы совместим с сопрограммами и co_await. Также Boost.Asio еще не поддерживает co_await из коробки. Поэтому мы напишем и то и другое, всего за сто строк кода. Начнем с универсального Future, который можно вернуть из сопрограммы, и который можно ждать в co_await. template struct Future { // На памяти экономить не будем, // поэтому данные будем хранить в некотором "общем состоянии", // результат будем копировать (или перемещать). struct SharedState { T value; std::experimental::coroutine_handle<> h; std::atomic is_ready; }; // Поддержка использования Future как результата сопрограммы. struct promise_type { std::shared_ptr s = std::make_shared(); Future get_return_object() { return {s}; } std::experimental::suspend_never initial_suspend() { return {}; } // SharedState переживет удаление promise_type в конце работы сопрограммы std::experimental::suspend_never final_suspend() { return {}; } void return_value(T value) const { s->value = std::move(value); if (s->is_ready.exchange(true)) s->h.resume(); } }; std::shared_ptr s; // Поддержка co_await. bool await_ready() noexcept { return false; } bool await_suspend(std::experimental::coroutine_handle<> h) noexcept { s->h = h; return !s->is_ready.exchange(true); } T await_resume() { return std::move(s->value); } }; Теперь пишем всё то же самое, но для случая когда сопрограмма не возвращает значений. template<> struct Future { struct SharedState { std::experimental::coroutine_handle<> h; std::atomic is_ready; }; struct promise_type { std::shared_ptr s = std::make_shared(); Future get_return_object() { return {s}; } std::experimental::suspend_never initial_suspend() { return {}; } std::experimental::suspend_never final_suspend() { return {}; } void return_void() const { if (s->is_ready.exchange(true)) s->h.resume(); } }; std::shared_ptr s; bool await_ready() noexcept { return false; } bool await_suspend(std::experimental::coroutine_handle<> h) noexcept { s->h = h; return !s->is_ready.exchange(true); } void await_resume() {} }; Это был наш Future. Теперь пишем обертки над async_* функциями Boost.Asio. Мы можем использовать тот же Future::promise_type, как будто это сопрограмма. Future coro_accept(boost::asio::ip::tcp::acceptor& acceptor, boost::asio::ip::tcp::socket& socket) { Future::promise_type p; acceptor.async_accept(socket, [p](auto error) { p.return_value(error); }); return p.get_return_object(); } Future coro_connect(boost::asio::ip::tcp::socket& socket, boost::asio::ip::tcp::endpoint endpoint) { Future::promise_type p; socket.async_connect(endpoint, [p](auto error) { p.return_value(error); }); return p.get_return_object(); } Если callback принимает больше одного параметра, то их можно сделать out-параметрами. В С++17 можно будет использовать tuple и structured bindings для распаковки. template Future coro_read(boost::asio::ip::tcp::socket& socket, Buffers bufs, std::size_t& bytes_read) { Future::promise_type p; socket.async_read_some(bufs, [p, &bytes_read](auto error, auto n) { bytes_read = n; p.return_value(error); }); return p.get_return_object(); } template Future coro_write_all(boost::asio::ip::tcp::socket& socket, Buffers bufs, std::size_t& bytes_written) { Future::promise_type p; async_write(socket, bufs, boost::asio::transfer_all(), [p, &bytes_written](auto error, auto n) { bytes_written = n; p.return_value(error); }); return p.get_return_object(); } И наконец сам код сервера, те же ~50 строк что и в оригинале boost::asio::io_service io_service; boost::asio::ip::tcp::resolver resolver(io_service); boost::asio::ip::tcp::resolver::query dst_query("arrowd.name", "80"); boost::asio::ip::tcp::resolver::iterator dst_iterator = resolver.resolve(dst_query); boost::asio::ip::tcp::endpoint dst_endpoint = *dst_iterator; Future proxy(boost::asio::ip::tcp::socket& src, boost::asio::ip::tcp::socket& dst) { char buf[4096]; for (;;) { std::size_t bytes_read; auto error = co_await coro_read(src, boost::asio::buffer(buf), bytes_read); std::cout << "read " << bytes_read << ' ' << error << '\n'; if (error) break; std::size_t bytes_written; error = co_await coro_write_all(dst, boost::asio::buffer(buf, bytes_read), bytes_written); std::cout << "write " << bytes_written << ' ' << error << '\n'; if (error) break; } // Закрытие сокетов вызовет ошибку в сопрограмме которая качает в другую сторону src.close(); dst.close(); } Future connect(boost::asio::ip::tcp::socket src) { boost::asio::ip::tcp::socket dst(io_service); auto error = co_await coro_connect(dst, dst_endpoint); std::cout << "connect " << error << '\n'; if (error) co_return; auto _ = proxy(src, dst); // Запускаем первую сопрограмму без ожидания co_await proxy(dst, src); // Запускаем вторую и ждем // Мы вышли из второй с какой-то ошибкой co_await _; // Ждем завершения первой } Future accept_loop() { boost::asio::ip::tcp::endpoint src_endpoint( boost::asio::ip::address_v4::loopback(), 8080); // localhost:8080 boost::asio::ip::tcp::acceptor acceptor{io_service, src_endpoint}; for (;;) { boost::asio::ip::tcp::socket src(io_service); auto error = co_await coro_accept(acceptor, src); std::cout << "accept " << error << '\n'; if (error) co_return; connect(std::move(src)); } } int main() { accept_loop(); io_service.run(); // Можно запустить параллельно в нескольких потоках } Код стал гораздо чище - пропали коллбеки. connect пришлось вынести из accept_loop в отдельную функцию, т.к. это отдельная сопрограмма. Всё что явно выделялось в динамической памяти теперь выглядит как локальные переменные. При этом оно всеравно живет в динамической памяти, в coroutine-state. Это позволяет передавать сокеты в proxy по ссылке - их время жизни привязно к connect. В данном коде отсутствует обработка исключений. Для поддержки исключений, Future должно уметь перебрасывать исключения при помощи std::exception_ptr.

Fluent API связь один к одному

#c_sharp #net #entity_framework


Не получается сделать связь один к одному, ошибка : 


  System.InvalidOperationException: 'Unable to determine the principal end of an
association between the types 'DataBase.Entities.Branch' and 'DataBase.Entities.Address'.
The principal end of this association must be explicitly configured using either the
relationship fluent API or data annotations.'


public class Branch
{
    public int Id { get; set; }
    public string Metro { get; set; }
    public string Name { get; set; }
    public string CommentToAddress { get; set; }
    public string Schedule { get; set; }
    public string SchedulePrivatePerson { get; set; }
    public string ScheduleGeneral { get; set; }
    public string ScheduleEntities { get; set; }
    public Bank Bank { get; set; }
    public Address Address { get; set; }
}

public class Address
{
    public int Id { get; set; }
    public string CountryCity { get; set; } //город
    public string StreetName { get; set; } // улица
    public string StreetType { get; set; } // "тип" улицы(улица, проспект, проезд)
- для оптимизации запроса к карте
    public string ClarifyingAddress { get; set; } //адрес после улицы
    public Branch Branch { get; set; }
}

 public class Bank
{
    public Bank()
    {
        Branches = new HashSet();
    }

    public int Id { get; set; }
    public string Name { get; set; }
    public string Url { get; set; }
    public float DollarBuy { get; set; }
    public float DollarSell { get; set; }
    public float EuroBuy { get; set; }
    public float EuroSell { get; set; }
    public System.DateTime UpdateTime { get; set; }
    public /*virtual*/ ICollection Branches { get; set; }
}

public class City
{
    public int Id { get; set; }
    public string Value { get; set; }
    public string Name { get; set; }
}


Configs

internal class  AddressConfig : EntityTypeConfiguration
{ public AddressConfig(DbModelBuilder modelBuilder) { HasKey(p => p.Id); Property(p => p.CountryCity).IsRequired(); Property(p => p.StreetName).IsRequired(); Property(p => p.StreetType).IsRequired(); Property(p => p.ClarifyingAddress).IsRequired(); } } internal class BankConfig : EntityTypeConfiguration { internal BankConfig(DbModelBuilder modelBuilder) { HasKey(p => p.Id); Property(p => p.Name).IsRequired(); Property(p => p.DollarBuy).IsRequired(); Property(p => p.DollarSell).IsRequired(); Property(p => p.EuroBuy).IsRequired(); Property(p => p.EuroSell).IsRequired(); Property(p => p.UpdateTime).IsRequired().HasColumnType("datetime"); modelBuilder.Entity().HasMany(p => p.Branches).WithRequired(p=>p.Bank); } } internal class BranchConfig : EntityTypeConfiguration { internal BranchConfig(DbModelBuilder modelBuilder) { HasKey(p => p.Id); Property(p => p.Metro).IsOptional(); Property(p => p.Name).IsOptional(); Property(p => p.CommentToAddress).IsOptional(); Property(p => p.CommentToAddress).IsOptional(); Property(p => p.SchedulePrivatePerson).IsOptional(); Property(p => p.ScheduleGeneral).IsOptional(); Property(p => p.ScheduleEntities).IsOptional(); Property(p => p.Schedule).IsOptional(); modelBuilder.Entity() .HasRequired(p => p.Bank) .WithMany(p => p.Branches); modelBuilder.Entity
() .HasRequired(p => p.Branch) .WithRequiredPrincipal(p => p.Address); } } class CityConfig: EntityTypeConfiguration { public CityConfig() { HasKey(p => p.Id); Property(p => p.Value).IsOptional(); Property(p => p.Name).IsOptional(); } } Context public class Context : DbContext { public Context():base("DbMap") { } static Context() { System.Data.Entity.Database.SetInitializer(new ContextInitializer()); } public DbSet Banks { get; set; } public DbSet Branches { get; set; } public DbSet Cities { get; set; } public DbSet
Addresses { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.Configurations.Add(new BankConfig(modelBuilder)); modelBuilder.Configurations.Add(new BranchConfig(modelBuilder)); modelBuilder.Configurations.Add(new AddressConfig(modelBuilder)); modelBuilder.Configurations.Add(new CityConfig()); } ConnectionString


Ответы

Ответ 1



Что-то вы перемудрили, для того что бы создать связь "один-к-одному" достаточно указать: modelBuilder.Entity
() .HasRequired(p => p.Branch) .WithRequiredPrincipal(p => p.Address); Поправил конфиги: public class AddressConfig : EntityTypeConfiguration
{ public AddressConfig() { Property(p => p.CountryCity).IsRequired(); Property(p => p.StreetName).IsRequired(); Property(p => p.StreetType).IsRequired(); Property(p => p.ClarifyingAddress).IsRequired(); HasRequired(p => p.Branch) .WithRequiredPrincipal(p => p.Address); } } public class BankConfig : EntityTypeConfiguration { public BankConfig() { Property(p => p.Name).IsRequired(); Property(p => p.DollarBuy).IsRequired(); Property(p => p.DollarSell).IsRequired(); Property(p => p.EuroBuy).IsRequired(); Property(p => p.EuroSell).IsRequired(); Property(p => p.UpdateTime).IsRequired().HasColumnType("datetime"); HasMany(p => p.Branches).WithRequired(p => p.Bank); } } public class BranchConfig : EntityTypeConfiguration { public BranchConfig() { HasRequired(p => p.Bank) .WithMany(p => p.Branches); } }

Сравнение скорости для команд оканчивающие цикл: jcxz vs cmp cx, 0 je

#ассемблер #условия #tasm


Добрый день, использую tasm (Turbo assembler) и мне стало жутко интересно какая же
конструкция работает быстрее : 

jcxz метка


или

cmp cx, 0
je метка


причем Vim не подсвечивает вариант с jcxz
    


Ответы

Ответ 1



Вторая конструкция будет дольше выполняться по тактам, следовательно медленнее. Не зря же команду придумали разработчики архитектуры x86... Подробности тут: Источник

Как наложить фильтр на ImageView

#java #android #android_imageview


Я хочу сделать фильтр на чёрно-белое изображение, это мне нужно для разных тем в
приложении. Как я понимаю для этого надо использовать

ImageView header = (ImageView) findViewById(R.id.drawer_header);
header.setColorFilter(R.color.my_color);


Я создал отдельный проект для тестирования и вот что получилось:



Но если я нажимаю на любую кнопку, кроме "убрать фильтр" (он ставит цвет android.R.color.transparent),
получается вот такая фигня:



Почему он делает всё фиолетовым? По логике всё должно работать. Приведу код применения
цвета полностью:

...

// Покрасить в красный
public void setRedColor(View v) {
ImageView header = (ImageView) findViewById(R.id.header);
header.setColorFilter(R.color.red);
}

// Покрасить в синий
public void setBlueColor(View v) {
ImageView header = (ImageView) findViewById(R.id.header);
header.setColorFilter(R.color.blue);
}

// Покрасить в зелёный
public void setGreenColor(View v) {
ImageView header = (ImageView) findViewById(R.id.header);
header.setColorFilter(R.color.green);
}

// Убрать краску
public void setNullColor(View v) {
ImageView header = (ImageView) findViewById(R.id.header);
header.setColorFilter(android.R.color.transparent);
}


Разметка:



    

    


Ответы

Ответ 1



Поменяйте каждый setColorFilter на setColorFilter(this.getResources().getColor(R.color. ... )) но getColor() не рекомендован после API 23, но можно воспользоваться v4 support либо другим getColor() для API>=23

Ответ 2



Разобрался с проблемой, надо было сделать так: header.setColorFilter(this.getResources().getColor(R.color.red), PorterDuff.Mode.ADD);

Не работает [(ngModel)] в md-select(Angular Material)

#angular2


Вывожу в компоненте


    
        {{food.viewValue}}
    
 


Браузер выдаёт ошибку: 

В классе пишу:

selected: any = [
    {viewValue: "Элемент 1", value: "0"},
    {viewValue: "Элемент 2", value: "1"},
    {viewValue: "Элемент 3", value: "2"},
    {viewValue: "Элемент 4", value: "3"},
];
selectedOne: string = "0";


Делаю всё по доке Material Angular
Но всё равно не хочется ставить элемент по умолчанию. Кто знает в чём может быть причина?
Angular cli 4.3; material 2.0
    


Ответы

Ответ 1



Директива ngModel расположена в модуле FormsModule из @angular/forms. Поэтому для ее использования нужно импортировать этот модуль в модуль где находит указанный компонент.

Ncurses с кодировкой cp866. Выводит заглавные русские символы как два символа, тильда(~) и заглавная латинская

#c #ncurses


Есть древний как помёт мамонта софт, писаный на С с использованием curses под SCO-Unix
и кодировку cp866. Я пытаюсь перенести его на linux (SLES 12) в связи понятно с чем.
Вместо curses(которую тупо не нашел) при компиляции использую ncurses. И вроде все
работает, но вот есть один косяк конкретно с заглавными русскими буквами - он их отображает
вот так: 

~Qтолбец:1


вместо

Столбец:1


Код:

#include 
#include "curses.h"

int main(int argc, char *argv[]) {
    initscr();
    mvaddstr(1, 0,
              "Тут текст в кодировке cp866.");
    getch();
}


Выводит:

~Rут текст в кодировке cp866.


Если весь тот-же текст параллельно выводить printf'ом, то выводится корректная строка.
    


Ответы

Ответ 1



Для исправления данной ситуации надо добавить вызов функции use_legacy_coding(2); после initscr(); the parameter is in the range 128-159, i.e., a C1 control code. If use_legacy_coding has been called with a 2 parameter, unctrl returns the parameter, i.e., a one-character string with the parameter as the first character. Otherwise, it returns ''~@'', ''~A'', etc., analogous to ''^@'', ''^A'', C0 controls. Такой код корректно отображает текст в однобайтовой восьмибитной кодировке CP866: #include #include "curses.h" int main(int argc, char *argv[]) { initscr(); use_legacy_coding(2); mvaddstr(1, 0, "Тут текст в кодировке cp866."); getch(); }

C# перенос слов в строке с разбивкой на определенную длину

#c_sharp


Есть строка: Quisque velit nisi, pretium ut lacinia in, elementum id enim. Nulla
porttitor accumsan tincidunt.

Нужно разбить ее на три части, но сохранять целые слова и переносить на следующую
строку только после окончания слова.
Например, разбиваем на три строки: 

Quisque velit nisi, pretium ut 
lacinia in, elementum id enim. 
Nulla porttitor accumsan tincidunt.


Сейчас использую вот такой простой код, но он режет целые слова:

int chunkSize = string.Length / 3;
int stringLength = string.Length;
for (int i = 0; i < stringLength; i += chunkSize)
{
    if (i + chunkSize > stringLength) chunkSize = stringLength - i;             
                      
    Console.WriteLine(string.Substring(i, chunkSize));
}


Получается на выходе:

Quisque velit nisi, pretium ut l
acinia in, elementum id enim. Nu
lla porttitor accumsan tincidunt
.


Подскажите как можно проще это реализовать? 

UPDATE

Важно: исходная строка может отличаться от приведенной выше. Может содержать любые
символы.

Нашел простое решение здесь https://stackoverflow.com/a/17571171/2127124

public static class ExtensionMethods
{
    public static string[] Wrap(this string text, int max)
    {
        var charCount = 0;
        var lines = text.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
        return lines.GroupBy(w => (charCount += (((charCount % max) + w.Length +
1 >= max) 
                        ? max - (charCount % max) : 0) + w.Length + 1) / max)
                    .Select(g => string.Join(" ", g.ToArray()))
                    .ToArray();
    }
}

    


Ответы

Ответ 1



Идея - найти индексы символов, по которым нужно разбить в идеале (на равные части). Найти все возможные варианты разбиений строки и выбрать вариант с наименьшей ошибкой. За ошибку я решил принять сумму абсолютных значений отклонений выбранных индексов от идеальных. static int Abs(int x) => x >= 0 ? x : -x; static void Main(string[] args) { // Входной текст var str = "Quisque velit nisi, pretium ut lacinia in, elementum id enim. Nulla porttitor accumsan tincidunt."; // Количество выходных строк var numOfParts = 3; // Перечень разделителей var delimeters = " "; // Индексы, по которым надо разбить в идеале var idealParts = Enumerable.Range(1, numOfParts - 1) .Select(x => ((str.Length - numOfParts + 1) * x + numOfParts / 2) / numOfParts) .ToArray(); // индексы всех имеющихся мест, по которым можно разбить var indices = str.Select((c, i) => (c: c, i: i)) .Where(t => delimeters.Contains(t.c)) .Select(t => t.i) .ToArray(); // indices.Length ^ numOfParts var numOfSp = Enumerable.Range(0, numOfParts - 1) .Aggregate(1, (m, x) => m * indices.Length); // Генерируем все возможные комбинации var splits = new int[numOfSp][]; for (int d = 0; d < numOfSp; ++d) { var z = d; splits[d] = new int[numOfParts - 1]; for (int i = numOfParts - 2; i >= 0; --i) { splits[d][i] = z % indices.Length; z /= indices.Length; } } // Для каждой комбинации подсчитываем ошибку var spWithEr = splits.Select(s => (s: s, er: s.Select((x, i) => Abs(indices[x] - idealParts[i])).Sum())) .ToArray(); // Находим минимальную ошибку var minEr = spWithEr.Min(t1 => t1.er); // Выбираем комбинацию с наименьшей ошибкой var minSp = spWithEr.First(t => t.er == minEr).s; // Отбираем индексы var sp = new[] { -1 }.Concat(minSp.Select(x => indices[x]) .Concat(new[] { str.Length })) .ToArray(); // Разбиваем на строки по индексам из sp for (int i = 0; i < sp.Length - 1; ++i) Console.WriteLine(str.Substring(sp[i] + 1, sp[i + 1] - sp[i] - 1)); Console.ReadLine(); } Вывод: Quisque velit nisi, pretium ut lacinia in, elementum id enim. Nulla porttitor accumsan tincidunt. Оверхед ли это - решать вам

Ответ 2



Разбиваем строку на слова с помощью метода Split и задаем максимальное количество символов в строке. Затем мы строим каждую строку из слов, разделяя их пробелами и проверяя не привысила ли длина текущий строки максимальную. Код получается довольно компактным, и пусть он скажет за себя) var inputString = @"Quisque velit nisi, pretium ut lacinia in, elementum id enim. Nulla porttitor accumsan tincidunt"; var words = inputString.Split(new Char[] { ' ' }); var maxLengthString = 53; int wordIndex = 0; var spaceLetter = " "; var currentLine = new StringBuilder(); while (true) { if (currentLine.Length + words[wordIndex].Length + 1 > maxLengthString)// Определяем не привысила ли текущая строка максимальную длину { Console.WriteLine(currentLine); currentLine.Remove(0, currentLine.Length); } currentLine.Append(words[wordIndex]); currentLine.Append(spaceLetter); wordIndex++; if(wordIndex == words.Length) { Console.WriteLine(currentLine); break; } }

Как проверить поддержку браузером spread operator'а?

#javascript #ecmascript_6


Возможно ли в JavaScript проверить, поддерживает ли браузер spread operator? Будет
ли в этом браузере работать следующая конструкция?

var array = [...arg];

    


Ответы

Ответ 1



в данном случае поможет eval и try..catch при попытке выполнить код с использованием spread оператора в браузере, который его не поддерживает будет кинуто исключение об ошибке синтаксиса, поэтому проверяющая функция может выглядеть так: function checkSpread() { try { return eval('[...[]]==""'); } catch (e) { return false; } } console.log(checkSpread()); Текущий сниппет, например в IE11 вернет false, а в Chrome - true Вместо eval так же можно использовать конструктор Function function checkSpread() { try { var func = new Function('return [...[]]'); return func() == ''; } catch (e) { return false; } } console.log(checkSpread());

Как быстро получить пропущенное в поле значение?

#mysql #sql #запрос




Есть таблица sample. Важный уникальный индекс UNIQUE( laboratory_prefix_id, sample_number
). Последний задаёт группу, в пределах которой не может быть повторяющихся sample_number.
Вопрос следующий - как быстро получить список пропущенных sample_number в пределах
запрошенной группы laboratory_prefix_id? И если не список, то хотя бы 1 наименьшее
значение.

Например, если искать в группе laboratory_prefix_id=5, то максимальный sample_number=15,
но перед ним пропущены значения 11, 12, 13, 14 - их (или хотя бы значение 11) хотелось
бы как-то получить (т.е. получить просто sample number пропущенных значений). Как это
быстро сделать?



Дамп таблицы для примера прикладываю

CREATE TABLE `sample` ( 
    `id` Int( 10 ) UNSIGNED AUTO_INCREMENT NOT NULL,
    `person_id` Int( 10 ) UNSIGNED NOT NULL,
    `laboratory_prefix_id` TinyInt( 3 ) UNSIGNED NOT NULL DEFAULT '1',
    `sample_number` Smallint( 5 ) UNSIGNED NOT NULL,
    `total_cost` Decimal( 6, 2 ) NOT NULL DEFAULT '0.00',
    `completion_date` Date NULL,
    `barcode` VarChar( 15 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL,
    `country_id` TinyInt( 3 ) UNSIGNED NOT NULL DEFAULT '20',
    `sample_priority` TinyInt( 1 ) UNSIGNED NOT NULL DEFAULT '1',
    `sample_note` VarChar( 255 ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL,
    `registration_date` Date NOT NULL,
    PRIMARY KEY ( `id` ),
    CONSTRAINT `UK_sample` UNIQUE( `laboratory_prefix_id`, `sample_number` ) )
CHARACTER SET = utf8mb4
COLLATE = utf8mb4_general_ci
COMMENT 'Образцы'
ENGINE = InnoDB
AUTO_INCREMENT = 57;

INSERT INTO `sample`(`id`,`person_id`,`laboratory_prefix_id`,`sample_number`,`total_cost`,`registration_date`,`completion_date`,`barcode`,`country_id`,`sample_priority`,`sample_note`)
VALUES 
( '15', '120', '8', '155', '0.00', '2017-08-18', NULL, '12-55fff', '20', '3', 'sdfsdfsdf' ),
( '22', '120', '7', '1', '0.00', '2017-08-11', NULL, NULL, '20', '1', NULL ),
( '32', '120', '7', '10', '0.00', '2017-08-19', NULL, NULL, '20', '1', NULL ),
( '33', '165', '5', '1', '0.00', '2017-08-19', NULL, NULL, '20', '2', NULL ),
( '34', '165', '5', '2', '0.00', '2017-08-19', NULL, NULL, '20', '2', NULL ),
( '35', '166', '5', '3', '0.00', '2017-08-19', NULL, NULL, '20', '3', NULL ),
( '36', '166', '5', '4', '0.00', '2017-08-19', NULL, NULL, '20', '3', NULL ),
( '37', '167', '5', '5', '0.00', '2017-08-19', NULL, NULL, '20', '2', '6лоло' ),
( '38', '168', '5', '6', '0.00', '2017-08-19', NULL, NULL, '20', '1', NULL ),
( '39', '168', '5', '7', '0.00', '2017-08-19', NULL, NULL, '20', '1', NULL ),
( '40', '168', '5', '8', '0.00', '2017-08-19', NULL, NULL, '20', '1', NULL ),
( '41', '168', '5', '9', '0.00', '2017-08-19', NULL, NULL, '20', '1', NULL ),
( '42', '168', '5', '10', '0.00', '2017-08-19', NULL, NULL, '20', '1', NULL ),
( '43', '173', '7', '2', '0.00', '2017-08-20', NULL, 'к', '17', '2', 'ккк' ),
( '44', '173', '5', '15', '0.00', '2017-08-18', NULL, 'ne', '20', '2', '=' ),
( '47', '180', '8', '5', '0.00', '2017-08-20', NULL, NULL, '20', '2', NULL ),
( '49', '120', '8', '161', '0.00', '2017-08-18', NULL, '12-55fff', '20', '2', 'sdfsdfsdf' ),
( '54', '120', '6', '212', '0.00', '2017-09-01', NULL, NULL, '20', '2', NULL ),
( '55', '120', '6', '213', '0.00', '2017-09-01', NULL, NULL, '20', '3', NULL ),
( '56', '120', '6', '214', '0.00', '2017-09-01', NULL, NULL, '20', '2', NULL );

    


Ответы

Ответ 1



SELECT @count FROM sample, (select @count := 0) dummy WHERE sample.laboratory_prefix_id = 5 AND (@count := @count+1) < sample.sample_number ORDER BY sample.sample_number ASC LIMIT 1; Не работает в случае, если для заданного sample.laboratory_prefix_id нет ни одной записи. Если начальное значение не равно 1, следует откорректировать как псевдотаблицу dummy, так и условие во WHERE. Вот более универсальный запрос (соответствует условию типа "найти первый свободный в группе laboratory_prefix_id = 5, но не менее sample.sample_number = 4"): SET @laboratory_prefix_id = 5; SET @min_sample_number = 4; SELECT @count FROM sample, (select @count := @min_sample_number-1) dummy WHERE sample.laboratory_prefix_id = @laboratory_prefix_id AND sample.sample_number > @min_sample_number-1 AND (@count := @count+1) < sample.sample_number ORDER BY sample.sample_number ASC LIMIT 1; Недостаток - тот же. Ну и запрос, избавленный от этого недостатка: SET @laboratory_prefix_id = 5; SET @min_sample_number = 4; ( SELECT @count FROM sample, (select @count := @min_sample_number-1) dummy WHERE sample.laboratory_prefix_id = @laboratory_prefix_id AND sample.sample_number > @min_sample_number-1 AND (@count := @count+1) < sample.sample_number ORDER BY sample.sample_number ASC LIMIT 1 ) UNION ALL ( SELECT @min_sample_number ) ORDER BY 1 DESC LIMIT 1;

Ответ 2



select s1.sample_number+1 from sample s1 left join sample s2 on s2.sample_number = s1.sample_number+1 AND s2.laboratory_prefix_id=5 where s1.laboratory_prefix_id=5 and s2.id is null order by s1.sample_number limit 1;

Python PyQt5 убрать кнопку Развернуть/Свернуть

#python #python_3x #pyqt5


Есть окно на PyQt5:

# -*- coding: utf-8 -*-

import sys
from PyQt5.QtWidgets import QApplication, QWidget


class Window(QWidget):
    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):
        self.setFixedSize(200, 350)
        self.setWindowTitle('Test')

        self.show()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = Window()
    sys.exit(app.exec_())


Как убрать ненужный пункт меню Развернуть/Свернуть?


    


Ответы

Ответ 1



В Qt для различных виджетов и диалоговых окон можно задавать WindowsFlags, меняющие их отображение. Чтобы сделать что-то нестандартное, нужно объявить наш виджет custom'ным, для этого используется флаг Qt::CustomizeWindowHint, Например, следующий код показывает только кнопку закрытия у диалогового окна в Qt (C++): QDialog d; d.setWindowFlags( Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint ); d.setWindowTitle("abcd"); d.show(); Подробнее: официальный пример работы с флагами Qt перечень Qt::WindowsFlags

Как добавить элемент в начало списка Java?

#java #списки


Пробовал с имя_списка.add() и имя_списка.set(). Результат нулевой. 

    BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
    ArrayList list = new ArrayList<>();
    for (int i = 0; i < 10; i++)
    {
        list.add(i, r.readLine());
    }
    for (int i = 0; i < 10; i++)
    {
        System.out.println(list.get(i));
    }

    


Ответы

Ответ 1



имя_списка.add(0,элемент_списка); UPDATE: BufferedReader r = new BufferedReader(new InputStreamReader(System.in)); ArrayList list = new ArrayList<>(); for (int i = 0; i < 10; i++){ list.add(0, r.readLine()); } for (String str : list){ System.out.println(str); } Так как появились подробности, дополню: если в задаче нет чёткой привязки на интерфейс List, то правильнее использовать класс Stack c его LIFO. BufferedReader r = new BufferedReader(new InputStreamReader(System.in)); Stack stack = new Stack<>(); for (int i = 0; i < 10; i++){ stack.push(r.readLine()); } while (!stack.isEmpty()){ System.out.println(stack.pop()); }

Круговая диаграмма с возможностью выбора секторов

#html #css #html5 #css3 #svg


Задача
Местоположение – круг разделен на 8 частей + еще одна в центре итого 9. Каждая эта
часть указывает на район Москвы, как говорят: “Живу на 4 часа” т.е. юго-восток или
6 часов - юг, а центр – это садовое кольцо.




Так как этот фильтр находиться внутри form и должен отправляться выбранная значения,
в html получается 9 скрытых radio прикрепленным на label, 8 трапеции 1 круг в центре.

С бордером не получается, они перекрывает друг друга, так как они на самом деле прямоугольник,
но со скрытыми краями.

Возможно ли сделать такую конструкцию на CSS или на чем угодно?

Заранее спасибо!
    


Ответы

Ответ 1



В данном случае не обязательно делать 9 радио кнопок. Достаточно будет одного скрытого инпута, а значения в него передавать из атрибута выбранного svg-элемента. Я бы сделал так с использованием jQuery: var loc = $('#location'); $('.filter').on('click', function() { $('.filter').attr('class', 'filter'); $(this).attr('class', 'filter active'); loc.val($(this).attr('data-location')); console.log(loc.val()); }); .filter { fill: #fff; stroke: #d1d1d1; stroke-width: 1; stroke-miterlimit: 10; cursor: pointer; transition: all 0.3s; } .filter:hover, .filter.active { fill: #dcba89; stroke: #dcba89; } .as-console-wrapper { max-height: 66px!important; }


Настройка ToolTip для Combobox WPF

#c_sharp #wpf #xaml


Имеется коллекция объектов:

public class Param
{
    public string Name { get; set; }
    public string Description { get; set; }
}


Эту коллекцию необходимо привязать к ComboBox так, чтобы в качестве элемента списка
был Name, а в качестве всплываемой подсказки при наведении на каждый элемент был Description.
Это легко делается:


              
                
                    
                       
                                    
              
 


Все бы ничего, но как сделать так, чтобы когда Description null или пустой, ToolTip
вообще не отображался. Сейчас отображается пустой квадратик. Вариант ниже не помог.
Заранее спасибо.

                
                
                    
                        
                        
                                
                                    
                                        
                                    
                                    
                                        
                                    
                                
                            
                                              
                                        
                                                
            

    


Ответы

Ответ 1



У вас как-то сложно. Значение null должно убирать ToolTip и так, так что проблема только с пустой строкой. Проще всего просто отловить это через конвертер. class NullIfEmptyConverter : IValueConverter { public object Convert(object value, Type targetType, object p, CultureInfo ci) => (string)value == string.Empty ? null : value; public object ConvertBack(object value, Type targetType, object p, CultureInfo ci) => throw new NotSupportedException(); } (или, как подсказывает @Андрей в комментариях, string.IsNullOrWhiteSpace((string)value) ? null : value). Ваш код получается таким: Не забудьте положить в ресурсы окна

Как указать браузеру , что информация на сайте обновилась, в частности в style.css не используя ctrl+f5?

#php #html #css



  Клиент это не всегда продвинутый пользователь, который знает как обновить страницу
при помощи ctrl+f5. Как выйти из этой ситуации? прочитал несколько форумов, но что-то
не понимаю как это сделать в style.css. Помогите пожалуйста! Файл размещён на сервере.
Можно по подробнее куда и что надо прописать? Прикладываю файл со стилями style.css.


@import "http://webfonts.ru/import/arnamuserif.css";

ul{
    margin: 0; padding: 0; list-style: none;
}
img{margin: 0; padding:0; border: 0;}
p{padding: 0 0 13px 0; margin: 0; }
a{ color: #2185c5; }

.clearfix:after {
    content: ".";
    clear: both;
    height: 0;
    font-size:0;
    visibility: hidden;
    display: block;
}

.clearfix {
    display: inline-block; /* Fixes IE/Mac */
}

/* Hides from IE-mac \*/
* html .clearfix {height: 1%;}
.clearfix {display: block;}
/* End hide from IE-mac */

html, body{
    margin: 0; padding: 0;
    min-width: 1000px;
}
body{
    background: #fff;
    font-family: 'Arian AMU Serif', Tahoma, sans-serif;
    color: #ffffff;
}

h1,h2,h3{
    font-family: 'Arian AMU Serif', Tahoma, sans-serif;
}

.p_header{
    position: fixed;
    left: 0; top: 0; right: 0;
    height: 58px;
    background: rgba(0,0,0,0.2);
    z-index: 10;
}
.p_header ul{
    display: block;
    width: 1000px; height: 58px;
    margin: 0 auto;
    padding: 0 0 0 30px;
}
.p_header ul li{
    float: left;
}
.p_header ul li a{
    display: block;
    font-size: 18px;
    line-height: 58px;
    color: #fff;
    text-transform: uppercase;
    text-decoration: none;
    text-align: center;
    padding: 0 16px;
}
.p_header ul li.active a{
    color: #36a1ff;
    text-decoration: underline;
}
.p_header ul li:first-child a{
    text-align: left;
    padding: 0 21px 0 0;
}
.p_header ul li:last-child a{
    text-align: right;
    padding: 0 0 0 21px;
}

.p_center{
    z-index: 1;
    min-height: 980px;
    padding: 58px 0 0 0;
}
.p_center.main{
    background: url(images/bg_main.jpg) top center fixed;
    height: 100%;
    position: relative;
    overflow: hidden;
    width: 100%;
}
.p_center.about{
    background: url(images/bg_about.jpg) top center fixed;
    height: 100%;
    position: relative;
    overflow: hidden;
    width: 100%;
}
.p_center.benefits{
    background: url(images/bg_benefits.jpg) top center fixed;
    height: 100%;
    position: center;
    overflow: hedden;
    width: 100%;
}

.p_center.location{
    background: url(images/bg_location.jpg) top center fixed;
    height: 100%;
    position: center;
    overflow: hedden;
    width: 100%;
}
.p_center.news{
    background: url(images/bg_news.jpg) no-repeat 50% 0;
}
.p_center.promotions{
    background: url(images/bg_promotions.jpg) top center fixed;
    height: 100%;
    position: relative;
    overflow: hidden;
    width: 100%;
}
.p_center.quality{
    background: url(images/bg_quality.jpg) no-repeat 50% 0;
}
.p_center.houses,
.p_center.house1,
.p_center.house2,
.p_center.house3,
.p_center.house4,
.p_center.house5,
.p_center.house6,
.p_center.townhouses,
.p_center.cottages,
.p_center.cotta1,
.p_center.cotta2,
.p_center.cotta3,
.p_center.cotta4,
.p_center.cotta5,
.p_center.cotta6,
.p_center.cotta7,
.p_center.cotta8,
.p_center.cotta9,
.p_center.cotta10,
.p_center.cotta11,
.p_center.cotta12,
.p_center.cotta13,
.p_center.cotta14,
.p_center.cotta15,
.p_center.cotta16,
.p_center.cotta17,
.p_center.cotta18,
.p_center.map1,
.p_center.map2,
.p_center.map3

{
    background: url(images/bg_houses.jpg) top center fixed;;
}
.p_center.contacts{
    background: url(images/bg_contacts.jpg) no-repeat 40% 0;
}
.p_center .inner{
    position: relative;
    width: 1000px;
    margin: 0 auto;
}
.p_center .main_map{
    position: absolute;
    left: 0; top: 30px;
    width: 190px; height: 167px;
    background: url(images/img_map.png) no-repeat;
}
.p_center .main_sale_count{
    position: absolute;
    left: 220px; top: 30px;
    width: 100px;
    text-align: center;
    font-size: 14px;
    line-height: 1.2;
}
.p_center a.main_logo{
    position: absolute;
    left: 392px; top: 30px;
    width: 215px; height: 168px;
    background: url(images/logo.png) no-repeat;
}
.p_center a.main_download_buklet{
    position: absolute;
    left: 642px; top: 30px;
    border: 1px solid #ffffff;
    text-transform: uppercase;
    border-radius: 10px;
    padding: 10px 10px 8px 10px;
    font-size: 14px;
    line-height: 14px;
    color: #ffffff;
    text-decoration: none;
}
.p_center .main_contacts{
    position: absolute;
    top: 30px; right: 0;
    padding: 0 0 0 30px;
    background: url(images/ic_phone.png) no-repeat 0 8px;
}
.p_center .main_contacts.map{
    z-index: 10;
    top: 80px; right: 50px;
}
.p_center .main_contacts div{
    color: #fff;
    font-size: 18px;
    line-height: 1.5;
}
.p_center .main_contacts button{
    color: #fff;
    font-size: 14px;
    line-height: 1;
    background: #36a1ff;
    border: 0;
    padding: 6px 20px;
    border-radius: 2px;
    cursor: pointer;
}
.p_center h1.main{
    position: absolute;
    left: 0; right: 0; top: 200px;
    text-align: center;
    font-size: 30px;
    line-height: 1.2;
    color: #fff;
    text-shadow: 1px -2px 2px #000;
    text-transform: uppercase;
}
.p_center .main_select_house{
    position: absolute;
    left: 0; right: 0; top: 794px;
    text-align: center;
}
.p_center .main_discount{
    position: absolute;
    left: 0; right: 0; top: 867px;
    text-align: center;
}

.p_catalog{
    position: absolute;
    left: 0; right:0; top: 470px;
    background: #ffffff;
    border-radius: 10px;
    height: 300px;
    padding: 0 25px;
}
.p_catalog .item{
    float: left;
    width: 190px; height: 300px;
    padding: 10px 8px;
    box-sizing: border-box;
    color: #000;
}
.p_catalog .item:hover{
    background: #c4c4b1;
}
.p_catalog .item .address{
    border-bottom: 2px dashed #e2dfe0;
    text-align: center;
    padding: 0 0 10px 0;
    margin: 0 0 15px 0;
}
.p_catalog .item .title{
    text-align: center;
    text-transform: uppercase;
    font-size: 13px;
    line-height: 1.4;
    margin: 0 0 10px 0;
}
.p_catalog .item .price{
    font-size: 18px;
    line-height: 1;
    text-align: center;
    color: #fff;
    background: #ff0000;
    border-radius: 3px;
    width: 120px;
    padding: 6px 0;
    margin: 0 0 15px 27px;
}
.p_catalog .item .image{
    width: 174px; height: 94px;
    margin: 0 0 15px 0;
    border-radius: 5px;
}
.p_catalog .item a.more{
    display: block;
    width: 172px; height: 30px;
    border: 1px solid #000;
    font-size: 14px;
    text-transform: uppercase;
    line-height: 30px;
    text-align: center;
    color: #000;
    border-radius: 5px;
    cursor: pointer;
}


.p_progress{
    background: #ffffff;
}
.p_progress .inner{
    position: relative;
    width: 1000px; height: 140px;
    margin: 0 auto;
}
.p_progress .hand{
    position: absolute;
    left: 0; top: 65px;
    width: 33px; height: 15px;
    background: url(images/img_pg_hand.png) no-repeat;
}
.p_progress .arrow{
    position: absolute;
    left: 60px; top: 65px;
    width: 890px; height: 22px;
}
.p_progress .arrow li{
    height: 22px;
}
.p_progress .arrow li.back{
    position: absolute; width: 100%;  z-index: 1;
    background: url(images/img_pg_arrow.png) no-repeat;
}
.p_progress .arrow li.active{
    position: absolute; z-index: 2;
    width: 0%;
    background: url(images/img_pg_arrow_a.png) no-repeat;
}
.p_progress .arrow li.knight{
    position: absolute;
    left: 0; top: -50px;
    min-width: 97px; height: 60px;
    background: url(images/img_pg_knight.png) no-repeat 100% 0;
    width: 15%;
}
.p_progress .arrow.about li.active{ width: 15%; }
.p_progress .arrow.about li.knight{ width: 25%; }
.p_progress .arrow.benefits li.active{ width: 30%; }
.p_progress .arrow.benefits li.knight{ width: 40%; }
.p_progress .arrow.location li.active{ width: 45%; }
.p_progress .arrow.location li.knight{ width: 55%; }
.p_progress .arrow.promotions li.active{ width: 55%; }
.p_progress .arrow.promotions li.knight{ width: 65%; }
.p_progress .arrow.quality li.active{ width: 65%; }
.p_progress .arrow.quality li.knight{ width: 75%; }
.p_progress .arrow.houses li.active{ width: 80%; }
.p_progress .arrow.houses li.knight{ width: 90%; }
.p_progress .arrow.contacts li.active{ width: 100%; }
.p_progress .arrow.contacts li.knight{ width: 100%; }





/*
.p_progress .arrow{
    position: absolute;
    left: 60px; top: 65px;
    width: 890px; height: 22px;

}
.p_progress .arrow:after{
    content: "";
    position: absolute;
    height: 22px; width: 50%;
    background: url(images/img_pg_arrow_a.png) no-repeat;
    z-index: 2;
}
*/

.p_footer{
    background: #ecece5 url(images/bg_footer_top.png) repeat-x;
    position: inherit;
    left: 0; bottom: 0;
    padding: 10px;
    width: 100%;
}
.p_footer .inner{
    position: relative;
    width: 1000px; height: 200px;
    margin: 0 auto;
}
.p_footer .logo{
    position: absolute;
    left: 0; top: 25px;
    width: 113px; height: 89px;
    background: url(images/logo_footer.png);
}
.p_footer .copyright{
    position: absolute;
    left: 140px; top: 50px;
    font-size: 14px;
    line-height: 1;
    color: #000;
}
.p_footer .convention{
    position: absolute;
    left: 450px; top: 50px;
    font-size: 14px;
    line-height: 1;
    color: #000;
}
.p_footer .contacts{
    position: absolute;
    right: 0px; top: 25px;
    color: #000;
    background: url(images/ic_phone2.png) no-repeat 0 27px;
    padding: 0 0 0 30px;
}
.p_footer .contacts label{
    display: block;
    font-size: 13px;
    line-height: 1;
    margin: 0 0 10px -30px;
}
.p_footer .contacts div{
    text-align: right;
    margin: 0 0 5px 0;
}
.p_footer .contacts a{
    display: block;
    font-weight: bold;
    color: #000;
    text-decoration: none;
}
.p_footer .contacts button{
    color: #fff;
    font-size: 14px;
    line-height: 1;
    background: #36a1ff;
    border: 0;
    padding: 6px 20px;
    border-radius: 2px;
    margin: 5px 0 0 -10px;
    cursor: pointer;
}


.p_map{
    margin: -58px 0 0 0;
    width: 100%;
    height: 1030px;
}
.p_map_info_box{
    position: absolute;
    left: -165px; top: 155px;
    background: #ffffff;
    width: 300px;
    border-radius: 10px;
    padding: 15px;
    color: #000;
    text-align: center;
    font-size: 14px;
}
.p_map_info_box2{
    width: 300px;
    color: #000;
    text-align: center;
    font-size: 14px;
    padding: 10px 0 0 0;
}
.p_map_info_box .title{
    line-height: 1;
    text-transform: uppercase;
    margin: 0 0 20px 0;
}
.p_map_info_box .title span{
    border-bottom: 1px solid #000;
}
.p_map_info_box p{
    margin: 0 0 10px 0;
}
.p_map_info_box .phone{
    margin: 0 0 20px;
}
.p_map_info_box .phone a{
    font-size: 18px;
    color: #000;
    text-decoration: none;
    font-weight: bold;
}
.p_map_info_box .notice{
    padding: 10px;
    background: #36a1ff;
    color: #ffffff;
}

.p_benefits{
    position: static;
    top: auto; left: 0; right: 0;
    text-align: center;
}
.p_benefits li{
    display: inline-block;
    width: 240px;
    margin: 0 0 10px 0;
    vertical-align: top;
}
.p_benefits h2{
    font-size: 18px;
    line-height: 1.2;
    text-transform: uppercase;
    margin: 0 0 10px 0;
}
.p_benefits img{
    margin: 0 0 10px 0;
}
.p_benefits p{
    font-size: 14px;
    line-height: 1.4;
}

.p_text{
    padding: 350px 30px 0 30px;
}
.p_text .img{
    text-align: center;
    margin: 0 0 20px 0;
}
.p_text h1{
    font-size: 18px;
    line-height: 1;
    margin: 0 0 20px 0;
    padding: 0;
    text-align: center;
    text-transform: uppercase;
}
.p_text p{
    font-size: 18px;
    line-height: 1.4;
    margin: 0 0 20px 0;
    text-align: justify;
}

.popup_back{
    display: none;
    background: rgba(0,0,0,0.6);
    position: fixed;
    left: 0; right: 0; top: 0; bottom: 0;
    z-index: 100;
}
.popup_callme{
    position: relative;
    margin: 200px auto 0 auto;
    width: 368px; height: 388px;
    background: url(images/bg_popup_callme.png) no-repeat;
}
.popup_callme .close{
    position: absolute;
    right: 35px; top: 70px;
    width: 16px; height: 16px;
    background: url(images/ic_popup_close.png) no-repeat;
    cursor: pointer;
}
.popup_callme form{
    padding: 100px 0 0 80px;
}
.popup_callme input{
    width: 210px;
    box-sizing: border-box;
    padding: 8px 10px;
    border: 1px solid #c2c2c2;
    margin: 0 0 20px 0;
    text-align: center;
    font-size: 14px;
    line-height: 1;
    color: #000;
}
.popup_callme button{
    width: 210px;
    box-sizing: border-box;
    padding: 8px 10px;
    border: 0;
    margin: 0 0 20px 0;
    text-align: center;
    font-size: 14px;
    line-height: 1;
    background: #36a1ff;
    color: #ffffff;
    cursor: pointer;
}

.p_quality{
    position: absolute;
    top: 280px; left: 0; right: 0;
    height: 639px;
    background: url(images/bg_quality.png) no-repeat;
    padding: 30px 0 0 85px;
}
.p_quality .text{
    width: 530px; height: 570px;
    overflow: hidden;
    overflow-y: scroll;
    color: #ffffff;
    padding: 0 100px;
}
.p_quality .text table{
    border-top: 1px solid #ffffff;
    border-left: 1px solid #ffffff;
}
.p_quality .text table td{
    border-right: 1px solid #ffffff;
    border-bottom: 1px solid #ffffff;
    vertical-align: top;
}
.p_quality .text::-webkit-scrollbar {
    width: 15px;
    background-color: rgba(0, 44, 68, 0.35);
    -webkit-border-radius: 10px;
    -moz-border-radius: 10px;
    -khtml-border-radius: 10px;
    border-radius: 10px;
}
.p_quality .text::-webkit-scrollbar-thumb {
    background-color: #36a1ff;
    -webkit-border-radius: 10px;
    -moz-border-radius: 10px;
    -khtml-border-radius: 10px;
    border-radius: 10px;
}

.p_promo{
    display: block;
    width: 562px; height: 162px;
    background: url(images/bg_promotion2.png) no-repeat -300px -330px;
    margin: 0 0 0 189px;
    font-size: 24px;
    line-height: 40px;
    text-align: center;
    padding: 40px 0 0 0;
    box-sizing: border-box;
}
.p_promo big{
    font-weight: bold;
}
.p_promo2{
  padding-top: 300px;
    position: relative;
}
.p_promo2:after{
    position: absolute;
    width: 800px;
    height: 360px;
    background: url(images/bg_promotion2.png) no-repeat 0 0;
    content: "";
}




.header-txt{
    text-transform: uppercase;
    border-top: 2px solid #fff;
    border-bottom: 2px solid #fff;
    padding: 5px 5px;
    font-size: 30px;
    margin-top: 20px;
    margin-bottom: 30px;
    display: inline-block;
    letter-spacing: 3px;
}
.header-info{
    text-align: center;
    font-size: 20px;
    padding-bottom: 15px;
    border-bottom: 2px solid #fff;
    text-align: left;
}


/* Gallery */
.gallery img{
    margin:5px;
    border:3px solid #fff;
}
a.photo:hover img{
border:3px solid #1E90FF;   
}   

.p_card{
padding: 330px 0px 0 0px;
}

    


Ответы

Ответ 1



Самый простой метод "заставить" браузера скачать обновлённый CSS файл, это динамически менять "параметр" для данного файла, например в PHP вы создаёте переменную: $vers = 1.0; и добавить параметр при подключения файла: В итоге, когда вы обновляете файл, вам надо просто зайти в код и в переменную $vers вставить другое значени $vers = 1.1; и т.д При загрузке страницы, браузер проверяет все подключаемые файлы, и если видит что все файлы "знакомые", проходит дальше, а когда вы передаёте параметр, для браузера это уже новый файл (хотя после ? ему параметр не нужен) и он просто скачивает данный файл.

Простой хук клавиатуры [закрыт]

#c_sharp


        
             
                
                    
                        
                            Закрыт. Данный вопрос необходимо конкретизировать. Ответы
на него в данный момент не принимаются.
                            
                        
                    
                
                            
                                
                
                        
                            
                        
                    
                        
                            Хотите улучшить этот вопрос? Переформулируйте вопрос,
чтобы он был сосредоточен только на одной проблеме, отредактировав его.
                        
                        Закрыт 2 года назад.
                                                                                
           
                
        
Находила только сложные решения, может кто подскажет самое простое:

есть приложение, оно проигрывает видео, надо что бы приложение сворачивалось при
любом нажатии клавиши клавиатуры, либо движении мыши, либо нажатии кнопки мыши. Как
это отследить? 
    


Ответы

Ответ 1



Если нужно отслеживать нажатия клавиш, движение и клики мышью именно глобально, то "просто" не получится, потому что данной функциональности в .NET из коробки попросту нету. Можно использовать WinAPI и глобальные системные хуки, и это, на самом деле, не так уж сложно, просто кода получается довольно таки не мало. Мне приходилось недавно решать похожую задачу и получился примерно вот такой достаточно универсальный класс (всё лишнее я постаралась убрать, но кода всё равно прилично): public sealed class GlobalHook : IDisposable { // Импортируем необходимые функции WinAPI, объявляем нужные для них структуры и константы private static class WinAPI { public static class Kernel32 { [DllImport("kernel32")] public static extern IntPtr LoadLibrary(string lpFileName); } public static class User32 { // KBDLLHOOKSTRUCT // https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms644967(v=vs.85).aspx public struct KeyboardHookStruct { public uint VKCode; public uint ScanCode; public uint Flags; public uint Time; public IntPtr dwExtraInfo; } // MSLLHOOKSTRUCT // https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms644970(v=vs.85).aspx public struct MouseHookStruct { public int X; public int Y; public uint MouseData; public uint Flags; public uint Time; public IntPtr dwExtraInfo; } // Константы WH_* public enum WindowsHook : int { KeyboardLowLevel = 13, MouseLowLevel = 14, } // Константы WM_* public enum WindowsMessage : int { KeyDown = 0x100, KeyUp = 0x101, SysKeyDown = 0x104, SysKeyUp = 0x105, MouseMove = 0x200, LeftButtonDown = 0x201, LeftButtonUp = 0x202, RightButtonDown = 0x204, RightButtonUp = 0x205, MiddleButtonDown = 0x207, MiddleButtonUp = 0x208, } public delegate int KeyboardHookProc(int code, WindowsMessage wParam, ref KeyboardHookStruct lParam); public delegate int MouseHookProc(int code, WindowsMessage wParam, ref MouseHookStruct lParam); [DllImport("user32")] public static extern int CallNextHookEx(IntPtr hHk, int nCode, WindowsMessage wParam, ref KeyboardHookStruct lParam); [DllImport("user32")] public static extern int CallNextHookEx(IntPtr hHk, int nCode, WindowsMessage wParam, ref MouseHookStruct lParam); [DllImport("user32")] public static extern IntPtr SetWindowsHookEx(WindowsHook idHook, KeyboardHookProc lpfn, IntPtr hMod, uint dwThreadId); [DllImport("user32")] public static extern IntPtr SetWindowsHookEx(WindowsHook idHook, MouseHookProc lpfn, IntPtr hMod, uint dwThreadId); [DllImport("user32")] public static extern bool UnhookWindowsHookEx(IntPtr hHk); } } // Дескрипторы хуков private readonly IntPtr _keyboardHookHandle; private readonly IntPtr _mouseHookHandle; // Хуки private readonly WinAPI.User32.KeyboardHookProc _keyboardCallback; private readonly WinAPI.User32.MouseHookProc _mouseCallback; // События public event KeyEventHandler KeyDown = (s, e) => { }; public event KeyEventHandler KeyUp = (s, e) => { }; public event MouseEventHandler MouseButtonDown = (s, e) => { }; public event MouseEventHandler MouseButtonUp = (s, e) => { }; public event MouseEventHandler MouseMove = (s, e) => { }; public GlobalHook() { // Создадим колбэки и сохраним их в полях класса, чтобы их не собрал GC _keyboardCallback = new WinAPI.User32.KeyboardHookProc((int code, WinAPI.User32.WindowsMessage wParam, ref WinAPI.User32.KeyboardHookStruct lParam) => { // Если code < 0, мы не должны обрабатывать это сообщение системы if (code >= 0) { var key = (Keys)lParam.VKCode; var eventArgs = new KeyEventArgs(key); // В зависимости от типа пришедшего сообщения вызовем то или иное событие switch (wParam) { case WinAPI.User32.WindowsMessage.KeyDown: case WinAPI.User32.WindowsMessage.SysKeyDown: KeyDown(this, eventArgs); break; case WinAPI.User32.WindowsMessage.KeyUp: case WinAPI.User32.WindowsMessage.SysKeyUp: KeyUp(this, eventArgs); break; } // Если событие помечено приложением как обработанное, // прервём дальнейшее распространение сообщения if (eventArgs.Handled) return 1; } // Вызовем следующий обработчик return WinAPI.User32.CallNextHookEx(_keyboardHookHandle, code, wParam, ref lParam); }); _mouseCallback = new WinAPI.User32.MouseHookProc((int code, WinAPI.User32.WindowsMessage wParam, ref WinAPI.User32.MouseHookStruct lParam) => { // Если code < 0, мы не должны обрабатывать это сообщение системы if (code >= 0) { // В зависимости от типа пришедшего сообщения вызовем то или иное событие switch (wParam) { case WinAPI.User32.WindowsMessage.MouseMove: MouseMove(this, new MouseEventArgs(MouseButtons.None, 0, lParam.X, lParam.Y, 0)); break; case WinAPI.User32.WindowsMessage.LeftButtonDown: MouseButtonDown(this, new MouseEventArgs(MouseButtons.Left, 0, lParam.X, lParam.Y, 0)); break; case WinAPI.User32.WindowsMessage.RightButtonDown: MouseButtonDown(this, new MouseEventArgs(MouseButtons.Right, 0, lParam.X, lParam.Y, 0)); break; case WinAPI.User32.WindowsMessage.MiddleButtonDown: MouseButtonDown(this, new MouseEventArgs(MouseButtons.Middle, 0, lParam.X, lParam.Y, 0)); break; case WinAPI.User32.WindowsMessage.LeftButtonUp: MouseButtonUp(this, new MouseEventArgs(MouseButtons.Left, 0, lParam.X, lParam.Y, 0)); break; case WinAPI.User32.WindowsMessage.RightButtonUp: MouseButtonUp(this, new MouseEventArgs(MouseButtons.Right, 0, lParam.X, lParam.Y, 0)); break; case WinAPI.User32.WindowsMessage.MiddleButtonUp: MouseButtonUp(this, new MouseEventArgs(MouseButtons.Middle, 0, lParam.X, lParam.Y, 0)); break; } } // Вызовем следующий обработчик return WinAPI.User32.CallNextHookEx(_mouseHookHandle, code, wParam, ref lParam); }); // В SetWindowsHookEx следует передать дескриптор библиотеки user32.dll // Библиотека user32 всё равно всегда загружена в приложениях .NET, // хранить и освобождать дескриптор или что-либо ещё с ним делать нет необходимости IntPtr user32Handle = WinAPI.Kernel32.LoadLibrary("user32"); // Установим хуки _keyboardHookHandle = WinAPI.User32.SetWindowsHookEx( WinAPI.User32.WindowsHook.KeyboardLowLevel, _keyboardCallback, user32Handle, 0); _mouseHookHandle = WinAPI.User32.SetWindowsHookEx( WinAPI.User32.WindowsHook.MouseLowLevel, _mouseCallback, user32Handle, 0); } #region IDisposable implementation private bool _isDisposed = false; public bool IsDisposed { get { return _isDisposed; } } public void Dispose() { if (_isDisposed) return; _isDisposed = true; // Удалим хуки WinAPI.User32.UnhookWindowsHookEx(_keyboardHookHandle); WinAPI.User32.UnhookWindowsHookEx(_mouseHookHandle); } ~GlobalHook() { Dispose(); } #endregion } А использовать этот класс можно очень просто, например в форме: public partial class MainForm : Form { protected readonly GlobalHook hook = new GlobalHook(); ... private void MainForm_Load(object sender, EventArgs e) { hook.KeyDown += (s, ev) => { // Так или иначе свернём приложение и т.д., // при необходимости можно проверить, какая именно кнопка была нажата ... }; // На hook.KeyUp, hook.MouseMove, hook.MouseButtonDown, hook.MouseButtonUp // можно повесить обработчики абсолютно точно так же // hook.MouseMove следует использовать осторожно, // оно вызывается достаточно большое число раз во время движения мыши } }

Изменение видимости элемента управления при обновлении свойства во ViewModel

#c_sharp #wpf #mvvm #события


К примеру, есть класс User. Есть ViewModel, в которой есть свойство LastUser. Свойство
периодически обновляется, генерируя NotifyPropertyChanged. На форме, поверх остальных
элементов, лежит невидимая панель. При обновлении свойства, необходимо показать панель
на несколько секунд, а затем спрятать. Как можно реализовать такое поведение? Есть
ли какой-нибудь EventTriger или DataTrigger?
    


Ответы

Ответ 1



Наиболее простым видится вынести в VM отдельное свойство для видимости панели и сделать метод, который запускать в сеттере LastUser: private async void ShowDetails() { IsVisiblePanel = true; await Task.Delay(TimeSpan.FromSeconds(1)); IsVisiblePanel = false; } Если не хотите делать это в VM - можно сделать во View, подписавшись вручную на PropertyChanged и делая тоже самое. Другой вариант, немного более замороченый - задействовать анимацию. Давайте будем действовать через прозрачность, у меня вот такая панель: Обратите внимание, у панели установлен DataContext, это важно, мы этим воспользуемся в дальнейшем. Давайте добавим в панель стиль и определим триггер, который будет скрывать панель когда она полностью прозрачна: Хорошо, а теперь управлять прозрачностью будет анимация, для этого запустим ее в EventTrigger Чтобы событие Binding.TargetUpdated возникало нужно его включить: DataContext="{Binding SelectedUser, NotifyOnTargetUpdated=True}" Теперь надо отключить панель в обычном режиме: Opacity="0" Ну и можно сделать анимацию посимпатичнее: Полный код панели, на всякий случай: PS: как раз вчера появилась статья на Хабре, в которой описаны возможные замены подписке на Binding.TargetUpdated. Получается всё можно сделать гораздо проще используя PropertyChangedTrigger из пакета Microsoft.Expression.Interactions

Как заставить рисовать хром “серую” иконку у расширения?

#javascript #google_chrome #chrome_extension


Мне нужно, чтобы иконка расширения при определенных условиях становилась "серой".
Ни как не могу найти способ заставить хром рисовать такую иконку.

Важный момент - "серые" иконки - это именно фича хрома. Т.е. вариант с заготоволенными
иконками с нормальными и серыми цветами меня не интересует.
    


Ответы

Ответ 1



Стоит пойти от обратного: почему иконка у вас "цветная"? Полагаю вы используете page_action, иконка которого всегда цветная/оригинальная. То, что вас интересует - это browser_action. Данное API позволяет поместить иконку приложения, которая по-умолчанию не активирована для каждого таба (и имеет серый цвет).

Изменение вида продуктов через javascript

#javascript #ajax #веб_программирование #django


Задача заключается в следующем.
Нужно сделать кнопку, которая переключает вид товаров на сайте(кубиками или списком).
Из моих идей:


Через ajax посылать запрос, а в ответ получать страницу с товарами в требуемом стиле
Через js редактировать html код товаров(какой-то костыль, кажется)
Другая страница в требуемом формате(самый худший вариант, как понимаете)






Прошу помочь с этой задачей. Как ее лучше решить? Может есть более простой способ?
    


Ответы

Ответ 1



В данном случае стоит просто манипулировать стилями: var products = document.getElementById('products'); document.getElementById('grid').addEventListener('click', function(){ products.classList.add('grid'); }); document.getElementById('list').addEventListener('click', function(){ products.classList.remove('grid'); }); .product { background: #CCC; width: 100%; height: 50px; border: 1px solid #FFF; box-sizing: border-box; float: left; } .grid .product { width: 50%; }


Ответ 2



А в чем, собственно, заключается костыльность второго варианта? Ставите две кнопки, которые будут переключать стили у блоков товара. И делаете количество выдаваемых единиц кратное количеству столбцов при изменении на "сетку". Насколько я знаю, таким способом пользуются все популярные торговые площадки.

Есть ли разница при SELECT * или SELECT `some_column` в PHP

#php #mysql #база_данных #select #производительность


Интересует насколько это влияет на производительность запроса в PHP

все запросы я делаю просто SELECT * ... LIMIT 0,20 и он постоянно подтягивает значения
всех столбцов (их примерно до 15), но использую из них я максимум 6-7.

У меня все время стоит лимит, а в базе строк больше > 10000 вот интересно это сильно
влияет на скорость? а что если дальше продолжать еще делать JOIN'ы ?
    


Ответы

Ответ 1



В большинстве случаев морочиться на эту тему не нужно. Вопрос про * в запросах - это такая trivia, которую нубы с придыханием рассказывают друг другу и которую можно прочитать в идиотских списках "25 способов ускорить свой скрипт в 100500 раз". Если удобно писать * и в базе нет блобов с гигазами варезов, а есть 15 несчастных варчаров, то никто не умрет от звездочки. Плюсы использования звездочки: при добавлении полей в таблицу не надо менять код запроса запрос становится читабельнее и короче Минусы использования звездочки: большой потенциальный объем данных, передаваемых в пхп, может сказаться на производительности если в запросе используется временная таблица, то наличие ненужных полей может катастрофически отразиться на времени запроса, поскольку во временную таблицу будут записываться все поля таблицы. Разумеется, лучше избегать запросов, которым требуется создание временной таблицы.

Ответ 2



использование * = "bad practice". минусы использование * : 1)если вы будете дальнейшей писать JOIN-i тогда у вас будет проблемы 2)если вы будете дальнейшей добавляет столбцы тогда они будет автоматический подключиться "без нужды" 3)лишние данные это зло 4)использование не дает вам прав наименование столбцов 5)может быть меньше но влияет на загрузку

AdMob Реклама не работает корректно

#java #android #android_studio #java_ee


LogcatEvent LogДобавляя тестовый ad unit ID(с офиц. сайта AdMob for Androids)(ca-app-pub-3940256099942544/6300978111),
всё работает отлично, и тип эта реклама поздравляет меня, что я смог её разместить.
Но стоит мне поставить мой ad unit ID(моего приложения), ничего не появляется...
Вот собственно файлы и их коды:

activity_main.xml:




    

    


Ответы

Ответ 1



Вы используете не то значение при инициализации AdMob. А именно - у вас в строке MobileAds.initialize(this, "ca-app-pub-8900900048721624/5809873614"); используется, видимо, ID баннера, а не ID приложения. Это 2 разных значения. Проверьте в настройках приложения в AdMob какое значение вам надо подставить при инициализации. Также захардкоженные размеры баннера не ОК. Лучше поставить ширину во весь экран и высоту по содержимому. Ну и выкладывать в общий доступ эти ID - плохая идея. Кто-то может их заюзать, накликать очень много с одного девайса и ваш акк заблокируют навсегда за накрутку и вы ничего не сможете доказать.