Страницы

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

пятница, 31 января 2020 г.

Очистка памяти от объектов класса в динамической памяти

#cpp


Доброго времени суток ,
Возник такой вопрос. Допусти у меня есть объект класса. Который в свою очередь имеет
просто поля и методы. То есть можно бы было заменить структурой (даже и без методов).
Место для него я выделяю в динамической памяти подобно этому 
 someObj* objPointer = new someObj();

То есть этот класс выступает в роли просто контейнера данных и работы с ними.
Вопрос в том, как правильно очистить память от этого класса? Допустим если у меня
в есть поле класса указатель на другой класс , то естественно , я пропишу в деструкторе
удаление подуровней. 
А как быть с самим классом ? В деструкторе если не брать удаление подуровней, больше
писать то и нечего , так как поля класса , не указатели , а статические переменные .
Нужно ли его удалять созданный класс с помощью такой конструкции ? 
delete objPointer

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


Ответы

Ответ 1



При вызове оператора delete для указателя на объект класса будет вызван его деструктор. В деструкторе вы должны освободить всю память, которую динамически выделили в конструкторе или других методах данного класса. Для тех полей класса, которые объявлены в статической памяти, будет вызван соответствующий деструктор автоматически. Если класс, к которому относится данный объект, является потомком другого класса, то потом будет вызван деструктор базового класса и его полей (не забывайте, что деструктор должен быть объявлен как виртуальный, иначе будет вызван деструктор только того класса, указателем на который вы пользуетесь. Могут быть утечки памяти и прочие Ужасные Вещи). И не забывайте, что разница между struct и class только в том, какие права доступа присваиваются полям данного типа по-умолчанию (public для struct и private для class). Больше никаких различий в типах объявления нет!

Ответ 2



Смотрите. Каждый объект является (точнее, может являться) ответственным за другие объекты. Часто ответственный объект содержит указатель на объекты, за которые он отвечает. В этом случае разумной политикой будет удалить эти объекты в своём деструкторе. Таким образом, когда внешний код удалит ответственный объект, при этом вызовется деструктор, и «внутренние» объекты тоже будут удалены. Более хорошая и современная идея такая: вместо обыкновенного указателя на объект хранить смарт-указатель. Тогда в деструкторе можно не заботиться о подчинённых объектах, они будут удалены автоматически. Если есть возможность автоматизировать часть логики программы, этим не стоит пренебрегать.

Ответ 3



Вы можете создавать и удалять экземпляр класса так, как написали. Тогда при его удалении c помощью delete работает деструктор класса, написанный Вами или созданный компилятором по умолчанию. Если Вы создали экземпляр в стеке: someObj obj , то этот же деструктор сработает при выходе из зоны видимиости или в конце программы.

Продвижение Андроид-приложения [закрыт]

#android #google_play #продвижение #раскрутка


        
             
                
                    
                        
                            Закрыт. Этот вопрос не по теме. Ответы на него в данный
момент не принимаются.
                            
                        
                    
                
                            
                                
                
                        
                            
                        
                    
                        
                            Хотите улучшить этот вопрос? Переформулируйте вопрос,
чтобы он соответствовал тематике «Stack Overflow на русском».
                        
                        Закрыт 4 года назад.
                                                                                
           
                
        
Написал своё первое приложение, это секундомер с таймером. Теперь хочу выложить его
в Play Market и даже не знаю, что дальше. Основа — платная версия, но думаю сделать
ещё урезанную бесплатную.

В общем, как я понял, это очень ответственный шаг (очень часто приходится видеть
плохие приложения чуть ли не в топе, а хорошие и интересные приложения всего с 10—50
загрузками). Но вот не знаю, что делать в первую очередь? Где выкладывать обзоры? Стоит
ли вкладывать деньги в продвижение (изначально решил продвигать бесплатно)? Приложение
имеет и английскую версию, и если с русскоязычной ещё более-менее понятно, то с английской
полный ноль.
    


Ответы

Ответ 1



Без лайт версии - не будет работать Запостите лайт версию в разные аппсторы (сейчас их много). Навскидку: Amazon, Samsung Apps, GetJar, Appoke и проч. Русскую версию выложите на 4PDA Прочтите книгу про маркетинг Android апп Не ленитесь отвечать на сообщения юзеров

Ответ 2



Секундомер-таймер платный? Не стоит. Сейчас не 2008 год, когда не было подобных приложений. Это все было раньше. Сейчас это все не работает. Большая конкуренция - большие компании - много хороших приложений + смотря на какой рынок вы ориентируетесь. На русский точно не стоит надеяться особо с платной версией. Выше Вам уже посоветовали что можно начать делать, согласен, добавлю только что еще можно выложить в SlideMe локализованную на анг язык версию и можно попробовать добавить AdMob. Кроме этого, если Вы этого не делали, то попробуйте: проанализируйте конкурентов вашего приложения и добавьте что-то особенное в свой апп. Если вкратце, то вот какой он должен быть примерно: - Должна быть симпатичная графика и UI - Как можно меньше багов и особенно крашей - Видео работы приложения - Красивые скриншоты - Особенность который нет у конкурентов - Можно сделать сайт/блог о приложении и добавить ссылку везде на этот сайт И еще отличным советом будет методика ребят из 37signals(авторов книги Rework): делайте приложение которым вы сами будете пользоваться. Отсюда будет очень много полезного, ведь вы сразу поймете свою аудитории и возможные косяки или сильные стороны своего приложения. Я думаю сейчас, чтобы приложение было более-менее популярным важна идея + качественная реализация + платное продвижение в спец. сайты(хотя бы в начале).

Ответ 3



маркеты AppBrain, AndroidPit Опубликуйте статью на Хабре: 100500 установок, заодно много ценных замечаний. Таких тестеров еще поискать ну и по поводу плтных установок, тоже верно. Для Android можно вот этими ребятами пользоваться http://advertmobile.net/

Анимация увеличение числа

#jquery #анимация #javascript


Есть ли в jquery, или написанная на стандартном js функция проигрывания увеличение
числа? Например:
Увеличение значения от 1% до 80%, быстро проиграв все значения промежуточные значения
(2,3,4...)?    


Ответы

Ответ 1



http://jsfiddle.net/8Sdpy/ — только ради спортивного интереса jQuery(function ($) // Добавляем hook "number" $.Tween.propHooks.number = { get: function ( tween ){ var num = tween.elem.innerHTML.replace(/^[^\d-]+/, ''); return parseFloat(num) || 0; }, set: function( tween ) { var opts = tween.options; tween.elem.innerHTML = (opts.prefix || '') + tween.now.toFixed(opts.fixed || 0) + (opts.postfix || ''); } }; // Используем $('#target') .html('1%') .animate({ number: 80 }, { duration: 'slow', postfix: '%', fixed: 2 }); }); Или совсем просто — http://jsfiddle.net/QGY28/ $('#num').animate({ num: 90 - 3/* - начало */ }, { duration: 5000, step: function (num){ this.innerHTML = (num + 3).toFixed(2) + '%' } });

Автоустановка расширения для google chrome

#google_chrome #chrome_extension


Как установить расширение в браузер хром программным путем.
Запуск файла на компе → расширение добавлено в хром

Как это реализовать, какой файл в хроме отвечает за управление установленными расширениями?

Кое как разобрался с документацией, создал файл  nojpnepbplnoojhiinbpegidccgolald.json
(в качестве имени использовал id приложения, его получил установив плагин к себе в
хром и скопировав его id) в папке  

C:\Users\<имя пользователя>\AppData\Local\Google\Chrome\Application\31.0.1650.63\Extensions


со следующим содержанием:

{
"external_crx": "C:\Sdsattings.crx",

"external_version": "1.0"
}


crx файл разместил на диске C, перезапускаю хром и ничего не происходит
    


Ответы

Ответ 1



Приветствую. В целях безопасности в Chrome на Mac / Windows можно устанавливать расширения только с Chrome Web Store. Т.е. по факту в Chrome добавляется информация о том какое расширение надо обновить и после запуска браузера он подгружает расширение. Windows 1.1. В Windows установка происходит через реестр в раздел: 32-bit HKEY_LOCAL_MACHINE\Software\Google\Chrome\Extensions 64-bit HKEY_LOCAL_MACHINE\Software\Wow6432Node\Google\Chrome\Extensions 1.2. Создать новый ключ (папка) вида aaaaaaaaaabbbbbbbbbbcccccccccc (ID расширения в Chrome Web Store) 1.3. Внутри этого ключа создать свойство update_url со значением https://clients2.google.com/service/update2/crx (ссылка на Chrome Web Store) Mac 2.1. Создать файл типа aaaaaaaaaabbbbbbbbbbcccccccccc.json (ID расширения в Chrome Web Store) 2.2. Содержимое файла должно быть таким { "external_update_url": "https://clients2.google.com/service/update2/crx" } 2.3. Положить его в папку: для определенного пользователя ~USERNAME/Library/Application Support/Google/Chrome/External Extensions/ для всех /Library/Application Support/Google/Chrome/External Extensions/ Вариант для Linux Для Linux можно устанавливать как с удаленного источника, так и с локального .crx файла 3.1. Создать файл типа aaaaaaaaaabbbbbbbbbbcccccccccc.json (ID расширения) 3.2. Содержимое файла должно быть таким при установке с локального файла { "external_crx": "/path/to/extension.crx", "external_version": "1.0" } при установке по ссылке (пример) { "external_update_url": "http://myhost.com/mytestextension/updates.xml" } 3.3. Положить файл в любую из папок (должен иметь права на чтение всеми): /opt/google/chrome/extensions/ /usr/share/google-chrome/extensions/ Также возможно установить расширение простым открытием .crx файла из Chrome, если браузер запустить с флагом –enable-easy-off-store-extension-install

Ответ 2



Почему бы не поискать ответ на официальном сайте? Developer's Guide -> Finishing -> Other Deployment Options http://developer.chrome.com/extensions/external_extensions.html

Передача переменных между функциями javascript

#функции #переменные #javascript


Например две функции:
var func1 = function(var1, var2,..., varN) {
    var first  = var1 + var2;
    var second = first + varN;
    ....
}

var func2 = function() {
}

как-то можно передать переменные, например first во вторую функцию не объявляя её
глобальной?    


Ответы

Ответ 1



Как вариант так: var func1 = function(var1, var2,..., varN) { var first = var1 + var2; var second = first + varN; .... return first; } var func2 = function(getFirst) { var first = getFirst(var1, var2,..., varN); } Вообще, функция должна что-то принимать и что-то возвращать. Лучше будет даже так: var func1 = function (args) {var first; .....; return first}, func2 = function (first)) {}; func1(func1(args)); Во избежания такой некрасивой вложенности лучше использовать временные переменные: var func1 = ...., func2 = ......, first = func1(args); func2(first)

Ответ 2



Например: Вернуть переменную из одной функции, получить во второй: function f1(){ var trololo = 345; return trololo; } function f2(){ var myTrololo = f1(); } Объявить вторую функцию внутри первой : function f1(){ var trololo = 345; function f2(){ var myTrololo = trololo; } } Использовать для связи какой-нибудь объект, к которому будут иметь доступ обе функции: var GodObj = {}; function f1(){ var trololo = 345; GodObj.lala = trololo; } function f2(){ var myTrololo = GodObj.lala; } Собственно вызвать вторую функцию из первой, с некоторым обычно необязательным параметром, но конечно тут зависит от того что эта функция делает function f1(){ var trololo = 345; f2(trololo); } functin f2(trololo){ if(typeof(trololo)!='undefined') myTrololo = trololo;// Если такой параметр есть }

Каким образом оценивать сложность алгоритма в нотации О-больше?

#алгоритм #javascript


Алгоритм поиска корня числа num. В алгоритме также используется sqrt, это приблизительный
корень.
function getsqrt (num, sqrt) {
  sqrt = 0.5*(sqrt+num/sqrt);
  var sqrtPrev = sqrt;
  while (Math.abs(sqrt-sqrtPrev) <= (sqrt-sqrtPrev)) {
    sqrtPrev = sqrt;
    sqrt = 0.5*(sqrt+num/sqrt);
  }
  return sqrt;
}

Какова сложность алгоритма? Линейная? Логарифмическая и т.д? Меня смущает просто
деления на 2. Мне кажется, это линейная O(n)или логарифмическая.
Обновление

Мои рассуждения следующие: мы имеем один цикл, значит степень первая. Но я не уверен,
что это линейная типа O(n). Потому что в задании есть 0.5*(sqrt+num/sqrt). Соответственно
мне кажется, что это ускоряет поиск корня, нежели мы бы делили просто на 2 или методом
перебора. Прав ли я, что это логарифмическая зависимость по основанию 2?    


Ответы

Ответ 1



Для Вашей функции сложно судить, какая у нее сложность - у Вас два аргумента. Поэтому, нужно либо фиксировать один аргумент, либо вводить зависимость между ними. Я использовал простое - sqrt = num/2. и пошел по самому простому пути - тестил на разных значениях аргумента и построить график (это один из способов узнать сложность). Мое мнение - сложность константная (или очень близка к ней). num десятые микросекунды (10^-7) 1 -> 32 2 -> 27 4 -> 24 8 -> 24 16 -> 23 32 -> 23 64 -> 23 128 -> 26 256 -> 24 512 -> 23 1024 -> 23 2048 -> 24 4096 -> 23 8192 -> 23 16384 -> 23 32768 -> 22 65536 -> 23 131072 -> 24 262144 -> 23 524288 -> 23 1048576 -> 24 2097152 -> 23 4194304 -> 24 8388608 -> 23 16777216 -> 23 33554432 -> 24 67108864 -> 23 134217728 -> 23 268435456 -> 24 536870912 -> 24 Как видно на первых проходах идет "прогрев" (это отрабатывает jit компилятор). Кстати, в Вашем коде есть одна ошибка - он иногда зависает. И зависает, если попытаться извлечь корень из числа, для которого он рациональный. (как минимум зависает на 4 и 10000). полный код для тестов и исправление (все тестилось на node.js). function getsqrt (num, sqrt) { sqrt = 0.5*(sqrt+num/sqrt); var sqrtPrev = sqrt; while (Math.abs(sqrt-sqrtPrev) < (sqrt-sqrtPrev)) { sqrtPrev = sqrt; sqrt = 0.5*(sqrt+num/sqrt); } return sqrt; } function test(num) { var start = new Date(); for (var i = 0; i < 10000000; i++) { getsqrt(num, num / 2); } var end = new Date(); return end.setTime(end.getTime()-start.getTime()) } for (var i = 1; i < 1000000000; i = i*2) { console.log(i + " -> " + test(i)); } P.S. В тегах указано с++, а код написан на JavaScript. Поэтому свой код я написал также на JavaScript. Обновление я разобрался, почему она константа. Потому что цикл обычно выполняется 1 раз или 0 (так у меня получается). Присмотритесь к условию while (Math.abs(sqrt-sqrtPrev) <= (sqrt-sqrtPrev)) sqrt-sqrtPrev используется в обеих частях! А если вспомните, то есть такое правило - не сравнивать на равенство вещественные числа (на больше-меньше можно, но осторожно, если числа близкие). Если там равно, то оно сработает только в том случае, если sqrt-sqrtPrev > 0 и немного повезет (на самом деле, если разница представима конечной двоичной дробью). Поэтому, сложность у алгоритма константная:).

Ответ 2



Если чуть-чуть изменить приведенный фрагмент программы следующим образом: function getsqrt (num, sqrt) { var sqrtPrev = sqrt; sqrt = 0.5*(sqrt+num/sqrt); while (Math.abs(sqrt-sqrtPrev) > 1e-5) { sqrtPrev = sqrt; sqrt = 0.5*(sqrt+num/sqrt); } return sqrt; } То получившаяся программа будет реализацией известного метода Ньютона для отыскания корня уравнения x^2 - num = 0. Про метод Ньютона известно, что (в некоторой окрестности решения) он обладает квадратичной сходимостью. Это означает, что на каждом следующем шаге значение невязки diff, то есть разности между значением sqrt и квадратным корнем из num, меньше, чем квадрат невязки, вычисленной на предыдущем шаге. Число итераций цикла зависит как от величины числа num, так и от величины требуемой точности. В примере эта величина фиксирована: 1e-5, но допустим, что она также может меняться. Обозначим требуемую точность именем eps. Тогда для метода Ньютона можно дать оценку числа итераций O(log log (num/eps)).

Ошибка java.lang.ClassCastException: [F cannot be cast to [Ljava.lang.Object / Java

#java


Использую библиотеку с открытым кодом JGraphX (http://www.jgraph.com/) для визуализации
графов. Возникла такая проблема, при попытке экспорта модели в XML-файл возникает ошибка
: java.lang.ClassCastException: [F cannot be cast to [Ljava.lang.Object. Я нашёл место
в коде библиотеки, где эта ошибка  генерится:  

/**
* Encodes the child objects of arrays, maps and collections.
* 
* @param enc Codec that controls the encoding process.
* @param obj Object whose child objects should be encoded.
* @param node XML node that contains the encoded object.
*/

protected void encodeElements(mxCodec enc, Object obj, Node node)
{
    if (obj.getClass().isArray())
    {         
        Object[] tmp = (Object[]) obj; // Здесь всё рушиться

        for (int i = 0; i < tmp.length; i++)
        {
            encodeValue(enc, obj, null, tmp[i], node);
        }
    }
    else if (obj instanceof Map) ...

При трассировке выяснилось, что obj действительно хранит массив из 10 числе типа
Float. Для понимания ситуации, я сделал следующий пример, чтобы разобраться :
public class Encast {

    public static void main(String[] args) {
        Object obj = createMassiv();
        Object[] tmp = (Object[]) obj;
    }

    public static Float[] createMassiv() {
        Float[] obj = new Float[10];
        for(int i = 0; i < obj.length; ++i) {
            obj[i] = (float) (i + 1);
        }
        return obj;
    }
}

В моём примере всё работает и преобразуется. Я не могу понять, в чём проблема в библиотеке,
и как я могу переписать так, чтобы не было ошибки.    


Ответы

Ответ 1



Проблема воспроизведется, если вы будете использовать тип float[] вместо Float[]. В Java массивы коварианты по типу, и т.к. тип Float является производным от Object, то и тип Float[] является производным от Object[]. Но примитивный тип float не является производным от ссылочного типа Object.

Защита от подделывания данных в ajax запросе самим пользователем

#запрос #ajax #клиент #защита #javascript


Всем привет, уже весь инет перерыл. Представим себе такую ситуацию. У нас есть игра
на js, в которой пользователь набирает очки. Эти очки нужно сохранить на сервер для
создания таблицы рекордов. Рекорд вместе с id пользователя и токеном через ajax передается
на php сервер. Если токен защищает аккаунт пользователя от стороннего вмешательства,
то как защитить рекорд от замены его самим пользователем? Ведь юзеру ничего не мешает
подменить запрос, взяв свой токен, и легко попасть на первое место. Переменная, хранящая
текущий результат на клиенте, зашита в функцию-обработчик. Поэтому пользователь ее
просто так не изменит. А вот запрос подделает запросто. Какие средства защиты нужно
использовать? Помогите!    


Ответы

Ответ 1



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

Ответ 2



Цитата с хабра: Написал метод который дублировал результат. В одном параметре передавался реальный, в другом шифрованный результат, методом замены символа по ключу. А далее, на сервере оба сравниваются и если что-то не соответствует, то – бан по аккаунту. И еще, сервер отправляет сгенрированный ключ при первом обращении. Клиент же, должен его вернуть с результатом. Без этого ключа, результат не примется и если все соответствует, и все проходит проверку, то результат записывается в БД, и генерируется новый ключ, который опять отдается клиенту. Это сделано для того, чтобы повторно запрос с результатом не могли отправить, как делается в программе «Charles».

IE 10-11 не видит условные комментарии

#html #internet_explorer #css #if


Подключаю в хедере 
 

IE8 видит нормально и меняет фон головы, а вот IE11 и 10 не воспринимают эту систему,почему
и как это исправить, на всякий

    


Ответы

Ответ 1



http://msdn.microsoft.com/en-us/library/ie/hh801214%28v=vs.85%29.aspx A page using Conditional Comments worked as intended in Windows Internet Explorer 9, but no longer works in Internet Explorer 10.

Ответ 2



Поддержка условных комментариев в стандартном режиме и режиме совместимости Internet Explorer 10 была удалена для улучшения взаимодействия и совместимости с HTML5. Это означает, что условные комментарии теперь обрабатываются как обычные комментарии, так же как в других браузерах. Это изменение может повлиять на страницы, написанные специально для Windows Internet Explorer, или страницы, использующие определитель браузера и подстраивающиеся под Internet Explorer. Страница, использующая условные комментарии, работает нормально в Windows Internet Explorer 9, но не работает в Internet Explorer 10. Используйте css хак: @media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) { /* стили только для IE10 */ }

Ответ 3



Да, спасибо для 10 и 11 версии подключается так Вы используйете IE

Тестирование в Java

#java #тестирование


Начнём с того, что я новичок, пользуюсь IDEA. Интересуюсь, как разработкой оффлайн
приложений, так и web-, даже про Android был бы не против, что-нибудь услышать, хотя
и меньше, чем про первые два варианта. Напишу сначала, что я знаю о тестировании:
1) В некоторых книгах (и не только) рекомендуется такой подход к программированию,
при котором перед тем, как писать непосредственно код, пишутся тесты. Если я правильно
понял, тесты пишутся ко ВСЕМ классам, которые будут в коде. Но во первых, написание
теста к классу требует такого же времени, что и написание самого класса, а иногда и
гораздо большего. Во вторых, в тех ситуация, которые я учёл, класс будет функционировать
исправно (за исключением опечаток), а в тех ситуациях, которые я не учёл, тест будет
проходится успешно (т.к. они не заложены в тест). И в третьих, иногда не знаешь как
будет выглядеть некий класс, до тех пор, пока его не реализуешь, более того, и после
реализации будет много раз видоизменятся, иногда кардинальным образом - например: попробовал
один подход - скорость отработки низкая, попробовал совершенно другой (с другим набором
классов и интерфейсов) - выше. 

Так вот стоит ли прибегать к такому подходу? И как быть с учётом всего, выше написанного?
Меня как-то панический страх берёт писать тесты все геттеры/сеттеры...

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

Просветите, как новичку воспользоваться автотестированием в различных ситуация (офф,
web)? Какие программные инструменты для этого использовать? Какой русскоязычной литературой
можно руководствоваться?

3) Может я ещё что-то упустил в области тестирования... Буду рад любым наставлениям
;)    


Ответы

Ответ 1



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

Ответ 2



Важна мера во всем. Тестируются обычно сложные случаи. А так вообще все тестировать никаких сил не хватит. Потом ведь надо будет писать тесты тестов (я серьезно). К тому же тестирование бывает разным: юнит тесты, нагрузочное тестирование, функциональное тестирование и т.д. Не зря среди прогерской братии есть специальность тестировщик/тестер. Прогер должен тестировать конечный результат своего труда. Скажем написали некий класс/иерархию выполняющую допустим скачивание контента из сети. Логичным было бы написать юнит тест проверяющий идентичность скачанного со скачиваемым. В общем идея проста: Вам мудрое руководство поставило некую задачу; Вы ее решили; Теперь надо доказать, что решение работает. Для этого пишете юнит тест (серию юнит тестов) доказывающих работоспособность вашего решения; Показываете руководителю; Профит. P.S. Касательно бинов. Если вам поставили задачу написать бины - значит придется писать юнит тесты на ваши бины. Такова се ля ви :)

Ответ 3



Вот хороший плагин для Eclipse, который определяет уровень, насколько ваш код покрыт тестами. http://eclemma.org/

Инспекция генератора имён

#java #инспекция_кода


Написал я программу, выложил на гитхаб (https://github.com/KaPaHgaIII/namegenerator).
Нет ли такого места, где можно показать свой код более опытным людям, чтобы указали
на недочёты?
    


Ответы

Ответ 1



1) cmdArguments.getGender().substring(0, 1).toLowerCase().equals("m") //жуть cmdArguments.getGender() == Genders.MALE //старые добрые enum а вот в getGender нужно писать что-то типо этого switch(gender) { case "male": return Gender.MALE; //и т.п. 2) Random randomizer = new Random(System.nanoTime()); //мелкая придирка, но System.nanoTime() писать не обязательно 3) в for (int i = 0; i < cmdArguments.getCount(); i++) { System.out.println(engine.generateName(cmdArguments.getLength())); } System.out.println лучше выносить в отдельный метод, причём лучше в отдельный класс (правило mvc) 4) catch (FileNotFoundException e) { System.out.println(e); } catch (IOException e) { System.out.println(e); } меняем на catch (Exception e) { System.err.println(e); //обратите внимание на err } 5) readData("male_names.txt"); здесь тоже бы хорошо было бы заюзать enum. А вдруг в будущем вы будете считывать данные не с файла, а с интернета? Будете url каждый раз указывать? 6) огромное количество s.substring(i, i + 2); А почему +2, а не +3? Не помешал бы мелкий комментарий рядом 7) Отдельное текстовое пояснение как работает алгоритм. Иначе он будет понятен только вам 0) Но главное, после моих рекомендаций не превратиться в Бориса из известной статьи Как два программиста хлеб пекли

Ответ 2



Ох, не люблю всех этих телепаций уровня "введите то, введите сё, введите хрень ту экзит". Чем стандартная командная строка не угодила-то? -g, --gender= m[ale], f[emale], b[oth] -l, --length= name length -n, --number= number of names to generate Понятно и без лишних телодвижений. Тем более что стандартный GNU getopt() для Java существует давно.

Как сделать счетчик уникальные просмотры на PHP?

#php


Как сделать с помощью "ip" уникальные просмотры?
$id = $_GET["id"];
qeurycount = mysql_query("SELECT count FROM news WHERE news_id='$id'",$link);
$resultcount = mysql_fetch_array($qeurycount);

    $newcount = $resultcount["count"] + 1;

    $update = mysql_query ("UPDATE news SET count='$newcount' WHERE news_id='$id'",$link);
}
    


Ответы

Ответ 1



Здесь что-то не понятное, вам нужна уникальность по IP? Но где проверка IP вообще? Где запись, если этот IP пришел впервые?

Ответ 2



Ребята, вы так запросто вставляете $_SERVER['REMOTE_ADDR']; в запрос, кто вам сказал, что там айпишник а не злобный sql inj? Кто мешает заголовок подменить? По теме - ip не является показателем уникальности, есть целые города сидящие через один ip При первом посещении, ставьте уникальный id в куки, или еще лучше в сессию, и по нему считайте. От чистки куков это в общем не спасет.

Ответ 3



При посещении страницы пользователем нужно записывать IP в отдельную таблицу, если в той таблице такой ip не был записан ранее CREATE TABLE `news_show` ( `ip` varchar(32) NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8; Количество всех просмотров echo mysql_result(mysql_query("SELECT COUNT(*) FROM news_show"),0); Запись посетителя $ip=$_SERVER['REMOTE_ADDR']; if(mysql_result(mysql_query("SELECT COUNT(*) FROM news_show WHERE ip='$ip' LIMIT 1"),0)==0) mysql_query("INSERT INTO news_show (`ip`) values('$ip')");

Ответ 4



На таком уровне php вам нужен как просто посылатель одного запроса: UPDATE news SET count = count + 1 WHERE news_id = :id Я бы не рекомендовал, впрочем, реализовывать счетчики в той же таблице. Таблица новостей вряд ли обновляется так часто, как счетчики, это может помешать кэшированию на стороне БД, да и приложение становится менее устойчивым - с отвалившимися каунтерами выжить можно, новостями - нет.

Как изменить цвет подсветки таких же переменных в PhpStorm ?

#phpstorm #php


Добрый день!
Специально пересмотрел все заданные вопросы про PhpStorm (на сей момент их было 39)
и не нашел ответа на свой вопрос.
Имеется PhpStorm 6-ой версии с Default визуальной цветовой схемой.
Создаю PHP файл и естественно, пишу PHP код.
Предположим, выделяю переменную $a, PhpStorm подсвечивает другие переменные $a, однако
очень тускло. 
Вопрос в следующем: как можно изменить цвет подсветки других таких же переменных ?
(чтобы было ярко и четко подсвечивались)
Копаюсь в Settings -> Editor -> Colors&Fonts -> PHP (все перебрал из списка, однако
подсветку таких же переменных не смог пока найти...
Подскажите пожалуйста что-нибудь по данному поводу.
Заранее спасибо!    


Ответы

Ответ 1



IDE Settings - Editor - Colors & Fonts - General - Identifier under caret

Bash скрипт - строчка, которая комментирует сама себя

#bash


Возможно ли написать на bash команду, которая комментирует сама себя в файле?    


Ответы

Ответ 1



Ну например: [vladd@Kenga] [19:49:21] [~] {0,120}$> cat selfmod.sh #!/bin/bash echo start T=$(mktemp -u) && sed '/DELETETHISLINE/s/^/#/' <$0 >$T && rm -f $0 && mv $T $0 echo finish [vladd@Kenga] [19:49:24] [~] {0,121}$> ./selfmod.sh start finish [vladd@Kenga] [19:49:29] [~] {0,122}$> cat selfmod.sh #!/bin/bash echo start #T=$(mktemp -u) && sed '/DELETETHISLINE/s/^/#/' <$0 >$T && rm -f $0 && mv $T $0 echo finish Если нужно не пересоздавать файл, можно так: #!/bin/bash echo start sed -i '/DELETETHISLINE/s/^/#/' "$0" echo finish Оказывается, sed умеет редактировать файл in place, так что получилось даже проще.

Ответ 2



Как мне кажется, я нашёл идеальное решение моей задачи. Тут самое главное переменная $LINENO, которая и показывает номер текущей строки в скрипте. Теперь можно делать скрипт, который после успешного выполнения команды сам себя комментирует. ls && sed -i ''$LINENO' s/^/#/' $0

Задача на скобочки

#cpp


Задача:
Некоторые скобочные структуры правильные, другие - неправильные. Ваша задача: определить,
правильная ли скобочная структура.
Вход: Слово в алфавите из двух круглых скобочек ( и ), [, ], {, }. Длина слова меньше
40001.
Выход: Либо 'NO', либо 'YES' без кавычек.
Вот текст моей программы, но она не проходит все тесты. Не пойму, где ошибка.  И
какие тесты она не проходит (не смог таких придумать).
int main()
{
    std::string s;
    std::cin >> s;
    std::stack < char > st;
    std::stack < char > st1;
    std::stack < char > st2;

    bool f = true, g = true, k = true;
    int index = 0;

    while (index < s.length() && f && g && k)
    {
        if (s[index] == ')')
        {
            f = (!st.empty());
            if (f)
                st.pop();
        }
        else
        if (s[index] == ']')
        {
            g = (!st1.empty());
            if (g)
                st1.pop();
        }
        else
        if (s[index] == '}')
        {
            k = (!st2.empty());
            if (k)
                st2.pop();
        }
        else
        if (s[index] == '(')
        {
            st.push(s[index]);
        }
        else
        if (s[index] == '[')
        {
            st1.push(s[index]);
        }
        else
        if (s[index] == '{')
        {
            st2.push(s[index]);
        }

        index++;
    }
    std::cout << (((k && f && g && st.empty() && st1.empty() && st2.empty()) ? "YES"
: "NO")) << std::endl;

}

Прошу помощи.
Обновление
Программа работает, но на каких-то тестах она работает неправильно (при загрузке
в систему проходят не все тесты). Какие там тесты, мне не известно. И я не могу выяснить,
при каких условиях она ошибается, прошу помочь именно в этом.
Просто хочу научиться работать со стеком. Не подумал о Вашем примере. Попробовал
реализовать заново с помощью трех стеков, Ваш пример теперь работает правильно, но
снова не проходит все тесты в системе. Код изменил в ответе. Посмотрите, пожалуйста.    


Ответы

Ответ 1



Я не вижу, чтобы у вас использовался флаг k в проверке while. Как вы думаете, что произойдет при входе "[{))" в вашу программу и является ли это правильным. Не указаны критерии правильности скобочных структур, к примеру, могут ли они быть пересекающимися. По хорошему, вам нужно считать количество каждого вида скобок, без всяких стеков и прочих наворотов: int round=0, rect=0, figure=0; Если опустилось ниже 0 во время прохождения, значит ошибка в структуре скобок и выполнить break, если по окончанию строки не все стали, снова равны нулю, тоже ошибка. UPDATE 1 (неверный) Тогда можно ограничиться одним стеком и организовать проверку только выталкиваемого из стека значения pop(), чтобы оно содержало аналогичную открывающую скобку. Ясли не ошибаюсь, этого достаточно: if (s[index] == ')') f = (!st.empty() && st.pop()=='('); if (s[index] == ']') g = (!st.empty() && st.pop()=='['); if (s[index] == '}') k = (!st.empty() && st.pop()=='{'); if (s[index]=='['||s[index]=='{'||s[index]=='(') st.push(s[index]); Соответственно проверка флагов в цикле и при выводе ответа (+ на пустоту стека) остается. UPDATE 2 (исправленный) @doomsday, прошу прощения, я не часто имею дело с С++, для возврата значения из стека надо использовать вместо pop() функция top(). То есть по идее следующий код должен решать поставленную задачу. #include #include #include using namespace std; int main(){ string str; stack st; int index = 0; bool f = true, g = true, k = true; cin >> str; while (index < str.length() && f && g && k) { char chr = str[index]; if (chr == '[' || chr == '{' || chr == '(') st.push(chr); if (chr == ')') f = (!st.empty() && st.top() == '('); if (chr == ']') g = (!st.empty() && st.top() == '['); if (chr == '}') k = (!st.empty() && st.top() == '{'); index++; } cout << (k && f && g && st.empty() ? "YES" : "NO") << endl; return 0; }

Ответ 2



Не помню решения этой задачи без рекурсии. Через рекурсию решается более-менее просто, вот так: class Braces { public: enum class br_type { _br_head, _br_round, _br_square, _br_figure }; Braces(br_type type, char* line) : _type(type) { int runner = 0; while(line[runner] == '(' || line[runner] == '[' or line[runner] == '{') { if (line[runner] == '(') _sub_braces.push_back(Braces(br_type::_br_round, &line[runner + 1])); else if (line[runner] == '[') _sub_braces.push_back(Braces(br_type::_br_square, &line[runner + 1])); else if (line[runner] == '{') _sub_braces.push_back(Braces(br_type::_br_figure, &line[runner + 1])); runner += _sub_braces.back().size(); } if (runner == strlen(line) && _type == br_type::_br_head) return; if (line[runner] == ')' && _type != br_type::_br_round) throw std::exception("NO"); if (line[runner] == ']' && _type != br_type::_br_square) throw std::exception("NO"); if (line[runner] == '}' && _type != br_type::_br_figure) throw std::exception("NO"); } int size() { return 2 + sum_sizes(_sub_braces); } int sum_sizes(vector& braces) { int res = 0; for (auto& br : braces) { res += br.size(); } return res; } br_type _type; vector _sub_braces; }; Код написал тут, т.е. не проверял, но идея рекурсии, думаю, ясна. Если внешний объект (с типом _br_head, которому передается вся строка) создатся без exception, то надо выводить ОК, иначе сообщение exception-а. Сделав nasty эксепшны, можно даже указать, на какой именно вложенности получена ошибка.

Ответ 3



#include #include #define TEST 1 #define VERBOSE 1 #if TEST const char * testInput[] = { "[ ]", "{ }", "( )", "< >", "rth(zxc<[{e r}wer]fdg>zxc)hj", "il.)rge{ }", "sdl fkv[flv,]", "fv[dsfnv>jn(bk) l", "(rg er>erg", "' } }; int main(void) { std::stack braceIndeces; std::string input; bool error = false; #if TEST #if VERBOSE std::cout << "Running tests..." << std::endl << std::endl; #endif for (size_t testInputIdx = 0; testInputIdx < sizeof(testInput) / sizeof(testInput[0]); ++testInputIdx) { input = testInput[testInputIdx]; std::cout << input << std::endl; #else #if VERBOSE std::cout << "Enter char sequence with braces..." << std::endl << std::endl; #endif std::cin >> input; #endif size_t inputIdx = 0; std::string::iterator itr = input.begin(); for (; itr != input.end(); ++itr, ++inputIdx) { char ch = *itr; size_t currentBracesIdx = braceIndeces.empty() ? (size_t)-1 : braceIndeces.top(); for (size_t i = 0; i < sizeof(braces) / sizeof(braces[0]); ++i) { if (ch == braces[i][OpeningBrace]) { braceIndeces.push(i); break; } else if (ch == braces[i][ClosingBrace]) { if (currentBracesIdx == i) braceIndeces.pop(); else { // error error = true; if (currentBracesIdx == (size_t)-1) { #if VERBOSE std::cout << "Error: unexpected brace char '" << ch << "' at " << inputIdx << ", braces not opened" << std::endl << std::endl; #else std::cout << "NO" << std::endl << std::endl; #endif } else { #if VERBOSE std::cout << "Error: unexpected brace char '" << ch << "' at " << inputIdx << ", should be '" << braces[currentBracesIdx][ClosingBrace] << "'" << std::endl << std::endl; #else std::cout << "NO" << std::endl << std::endl; #endif } } break; } // else tested char is not a brace char } if (error) break; } if (error) error = false; else { if (!braceIndeces.empty()) { #if VERBOSE std::cout << "Error: unclosed braces, '" << braces[braceIndeces.top()][ClosingBrace] << "' expected at the end" << std::endl << std::endl; braceIndeces = std::stack(); #else std::cout << "NO" << std::endl << std::endl; #endif } else std::cout << "YES" << std::endl << std::endl; } #if TEST } #endif return 0; }

Удаление элементов в ArrayList

#java


Как известно, после удаления элемента из середины списка ArrayList, часть массива,
которая следовала после данного элемента, перезаписывается на позицию влево, чтоб перекрыть
пустую ячейку. Если стоит задача удалить несколько элементов из середины списка одной
операцией (т. е. чтоб избежать многоразовой перезаписи массива), как это можно сделать?    


Ответы

Ответ 1



Как обычно - наследованием: public class MyArrayList extends ArrayList { public void remove(int startIndex, int endIndex) { //здесь и придумывайте свой гениальный код } }

Ответ 2



Используйте методы removeAll и sublist. sublist - для создания коллекции (пула элементов), которую нужно удалить. А removeAll уже для удаления элементов. Пример кода: public static void main(String[] args){ List list = new ArrayList<>(); list.add(1); list.add(2); list.add(3); list.add(4); list.add(5); list.add(6); list.add(7); list.add(8); List sublist = list.subList(2,5); // Удаляем с 2 по 4й элемент включительно list.removeAll(sublist); System.out.println(list); //[1, 2, 6, 7, 8] } } //В одну строку public static void main(String[] args){ List list = new ArrayList<>(); list.add(1); list.add(2); list.add(3); list.add(4); list.add(5); list.add(6); list.add(7); list.add(8); list.removeAll(list.subList(2,5)); System.out.println(list); //[1, 2, 6, 7, 8] } }

Ответ 3



использовать removeAll(Collection c) наследовать и использовать removeRange(int fromIndex, int toIndex)

Ответ 4



Не нужно ничего наследовать, вреда от этого больше, чем пользы. Нефинальные классы контейнеров были ошибкой. Условимся, что из списка длины n нужно удалить m элементов. Формализую вопрос: m удалений, по O(n) каждое, стоит O(m×n); как можно ускорить процесс? Пользуясь тем, что ArrayList#set стоит O(1), нужно сначала отметить все элементы как удалённые: list.set(index, REMOVED); где REMOVED — это приватная константа, которая в обычных условиях в списке не окаженся: private static final Object REMOVED = new Object(); Дженерики будут мешать вставке произвольных Objectов, поэтому придётся воспользоваться стиранием и сделать unchecked cast. ((List) list).set(index, REMOVED); После этого в листе есть посторонние элементы. Осторожно: list.get(removedIndex) приведёт к ClassCastException, подробнее — см. heap pollution. Теперь нужно удалить все элементы, которые отмечены для удаления. Вызов list.remove(REMOVED) удалит только первое вхождение; нам нужен метод removeAll, который удалит все элементы переданной коллекции из данного списка: list.removeAll(COLLECTION_OF_REMOVED); где private static final Collection COLLECTION_OF_REMOVED = Collections.singleton(REMOVED); Это произойдёт за O(n), после чего объектов REMOVED в списке не будет и его снова можно будет безопасно читать. Gist с решением проблемы и комментариями См. также метод removeIf из Java 1.8.

Вопрос про админки в Ruby On Rails

#ruby_on_rails


Здравствуйте, нужно понять, какая сейчас админка:

1) поддерживает Ruby On Rails последней версии под номером 4.2

2) русифицированная, вместе с ошибками валидации, либо понять как это сделать максимально
просто и быстро и какими gem'ами нужно догнаться
    


Ответы

Ответ 1



Хорошая админка - это Active Admin. Active admin документация Все это ставится с гемом Devise. С моей версией ruby 2.2.1 версия Devise gem 'devise', '~> 3.4.1' хороший туториал по настройке Devise В итоге в гем файле должно выглядеть как-то так: gem 'activeadmin', github: 'activeadmin' gem 'devise', '~> 3.4.1'

Ответ 2



Я в большинстве проектов использую https://github.com/activeadmin/activeadmin Работает в содружестве с гемом devise, поэтому его также придётся добавить в Gemfile

Ответ 3



Еще есть очень простая и удобная админка rails_admin: https://github.com/sferik/rails_admin Интегрируется с Devise (для регистрации и аутентификации), Papertail (для хранения истории изменений) и Cancan (для разделения прав пользователей)

С#: передача параметров с POST запросом

#c_sharp #веб_программирование #клиент_сервер


Столкнулся с интересно задачей - требуется на сервер послать параметры и в ответ
получить XML.

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(is_card_URL);
request.Method = "POST";

byte[] bytes = Encoding.UTF8.GetBytes(params_);
request.ContentLength = bytes.Length;

using (var stream = request.GetRequestStream())
{
    stream.Write(bytes, 0, bytes.Length);
    stream.Close();
}

HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream stream2 = response.GetResponseStream();
StreamReader reader = new StreamReader(stream2);

string data = reader.ReadToEnd();

reader.Close();
stream2.Close();


Сам код работает, но нужно вместе с УРЛ также послать параметры (допустим, а,b,c)
Я пробовал дописывать в УРЛ (...?a=1&b=2&c=3), но сервер не видит параметров, в ответе
он пишет, что параметры не переданы.

Подскажите пожалуйста, как в данном случае можно передать параметры на сервер?
    


Ответы

Ответ 1



Параметры для POST запроса передаются немного по-другому: string postParameters = "a=1&b=2&c=3"; HttpWebRequest request = (HttpWebRequest)WebRequest.Create(is_card_URL); request.Method = "POST"; request.ContentLength = postParameters.Length; using (var writer = new StreamWriter(request.GetRequestStream())) { requestWriter.Write(postParameters); } Если передаваемая строка может содержать недопустимые символы, ее предварительно нужно закодировать: string parameters = ...; string postParameters = HttpUtility.UrlEncode(parameters); Дополнительно можно указать желаемую кодировку: using (var writer = new StreamWriter(request.GetRequestStream(), Encoding.UTF8)) В общем случае, когда нужно передать произвольные данные, используется байтовый массив: byte[] postData = ...; request.ContentLength = postData.Length; using (var stream = request.GetRequestStream()) { stream.Write(postData, 0, postData.Length); } Тогда пример с передачей строки можно свести к следующему коду: string parameters = ...; byte[] postData = Encoding.UTF8.GetBytes(HttpUtility.UrlEncode(parameters)); request.ContentLength = postData.Length; using (var stream = request.GetRequestStream()) { stream.Write(postData, 0, postData.Length); }

Ответ 2



Если нет принципиальной необходимости работать именно через WebRequest/WebResponse, то самый простой способ - использование System.Net.WebClient.UploadValues using (WebClient client = new WebClient()) { byte[] response = client.UploadValues(is_card_URL, new NameValueCollection() { { "a", "1" }, { "a", "2" }, { "c", "3" } }); string result = UTF8.GetString(response); }

Ответ 3



В отличие от GET-запроса POST получает параметры в теле, а не в строке запроса, а размер передаваемых данных указывается в заголовке ContentLength. Сделайте например так: byte[] bytes = Encoding.UTF8.GetBytes(queryString); webRequest.ContentLength = bytes.Length; using (var stream = webRequest.GetRequestStream()) { stream.Write(bytes, 0, bytes.Length); stream.Close(); } Плюс небольшая ремарка: никогда не используйте просто Close/Dispose без using или try для потоков, запросов и прочих освобождаемых ресурсов. Это источник потенциальных проблем

Функция free() не освобождает память

#c


Подскажите, у меня есть вот такая функция в которой используется free():

void removeNode(struct Node** t) {
    int key;
    struct Node ** rm;
    struct Node *replace;
    puts("Vvedite iskomiy key");
    scanf("%d", &key);
    (*rm) = searchKey(*t, key);
    if (rm == NULL) {
        puts("not found");
        return;
    }
    if ((*rm)->llink == 1 && (*rm)->llink == 1) {
        if ((*rm)->p->r == (*rm)) {
            (*rm)->p->r = (*rm)->p->p;
            (*rm)->p->rlink=1;
        }
        else {
            (*rm)->p->l = getLLink((*rm)->p->key, (*rm)->p);
             (*rm)->p->llink=1;
            }
        free(*rm);
        *rm=NULL;
        return;
    }
    if ((*rm)->llink != 1 && (*rm)->llink != 1) {
        if ((*rm)->p->r == (*rm)) {
            (*rm)->p->r = (*rm)->r;
        }
        else (*rm)->p->l = (*rm)->r;
        connectNode(&t,(*rm)->l);
        free(*rm);
        *rm=NULL;
        return;
    }
}


После выполнения этой функции я все равно при обходе дерева могу попасть в этот узел.
Для желающих скомпилить, код я выложил сюда:
http://www.codeshare.io/mmoQg
Для того, что бы попасть в это условие можно выполнить следующую последовательность
действий:

1
15
1
1
35
1
1
45
1
2
45


После этого *tail- указатель на максимальный элемент, должен принять значение NULL
после удаления, но по факту там остается 45...
    


Ответы

Ответ 1



Если почитать документацию на функцию free(), можно увидеть такую строчку: Notice that this function does not change the value of ptr itself, hence it still points to the same (now invalid) location. Перевод: Заметьте, что эта функция не изменяет значение переданного указателя, он указывает на ту же область памяти, но она больше не может быть использована. Тот факт, что аллокатор не очистил значение, располагающееся по адресу, на который указывает указатель tail, не значит, что он не освободил этот участок памяти. Этот участок возвращается в пул свободной памяти и при последующих вызовах malloc он может быть заново выделен. Насколько мне известно, стандарт не гарантирует того, что память, освобождёная при помощи free() будет очищена. Здесь объяснено более подробно.

Несколько вопросов по C# обфускации (SmartAssembly, internal функции)

#c_sharp #обфускация


Экспериментирую с различными обфускаторами, чтобы защитить свой код от повторного
использования.  

Основная задача - сделать анализ с целью повторного использования настолько трудоемким,
чтобы дешевле было написать свой код, а не использовать мой. Уточню - не преследую
цель сделать анализ НЕвозможным,- просто, максимально усложнить!  

Пока остановился на SmartAssembly (версии 6). Деобфусцировал с помощью de4dot. Результат
оценивал в Reflector. В связи с этим есть ряд вопросов. В вопросах подразумевается,
что анализируемый exe или dll был ранее обфусцирован SmartAssembly. 

Вопросы:  


Можно ли с помощью какого либо метода (деобфускация, создание дампа процесса, отладка
или что либо другое) без значительных трудозатрат восстановить исходный код (можно
без имен переменных) internal и private функций с условием, что они не вызываются из
public функций? Если можно, то как?  
Аналогичный вопрос по поводу исходных имен параметров функций и локальных переменных,
используемых в internal и private функциях.  
Какой обфускатор посоветуете использовать вместо SmartAssembly (только чтобы лицензия
была не дороже 150-200$)?  


Несколько наблюдений (исходя из моих экспериментов):  


De4dot не восстанавливает имена локальных переменных после SmartAssembly (только
переименовывает исходя из их типов для облегчения анализа). А вот структуру кода нормально
восстанавливает. Еще восстанавливает имена параметров публичных функций.  
internal и private функций я не нашел в восстановленном с помощью De4dot файле. Причем,
их код не находится даже если вызываешь прямо из него (из кода internal или private
функции) public функцию (в то время как ее вызов из публик функции виден http://prntscr.com/78pxf8
и http://prntscr.com/78pxhs)  
Однако если приватная функция вызывается публичной, то ее можно обнаружить и распознать
структуру .

    


Ответы

Ответ 1



Имена локальных переменных не хранятся в скомпилированной в IL сборке. Они будут уничтожены независимо от использования обфускации. Имена локальных переменных не извлекает деобфускатор, а генерирует декомпилятор. Аргументы функций являются частью публичного интерфейса, поэтому хранятся. Как и всё публичное, они могут быть обфусцированы, если обфускатор не совсем бесполезный. Что такое "приватная функция, которая не вызывается из публичной функции"? А откуда она тогда вызывается? Или функция в конце концов будет вызвана по цепочке публичным кодом (и тогда её код будет в сборке), или она будет полностью отсутствовать в сборке (обфускаторы могут выкидывать неиспользуемый код более дерзко, чем компиляторы). Какой обфускатор посоветуете использовать вместо SmartAssembly (только чтобы лицензия была не дороже 150-200$)? Никакой. Обфускаторы для .NET — пустая трата денег. Чем меньше вы заплатите денег, тем меньше потеряете. Если хочется затруднить декомпиляцию, найдите любой обфускатор, который умеет обфусцировать названия публичных методов. Остальное вообще мусор, потому что всё равно бОльшая часть кода не приватная.

Ответ 2



Если функция/метод вызывается, то ее можно найти. Другое дело, что компилятор может ее заинлайнить и она станет частью вызывающей функции. Другой вариант - функция не вызывается и компилятор может ее выбросить. Соотвественно, ее потом никак не найти. То, что Вы не можете найти свою функцию ещё не значит, что ее там нет и ее сложно найти. Анализ все равно начинается с публичных функций и потом спускаются вниз. Имя функции/переменной для компилятора обычно ничего не значит. К примеру, если это переменная цикла, то главное, что бы совпадал тип. А ее имя не имеет никакого значения. Если функция используется локально (локально в понятии компилятора), то ее можно переименовать. Другое дело публичные методы, к которым могут обращаться с внешнего мира. Тут просто так не переименуешь - поломается весь код. Я не особо силен в .NET, но могу сказать, что самый лучший обсфукатор - это Ваш мозг. В большинстве случаев Ваш код понятен только Вам и туда внутрь мало кто будет смотреть. Если кому то нужно будет его использовать - главное будет разобраться с интерфейсом. А что там внутри и как оно обсфуцировано - это проблемы автора. Я лично против обсфукаторов. Это просто способ купить псевдоспокойствие за деньги, не более. Половина обсфукаторов только переименовывает имена переменных. Структуру кода даже не трогает. Некоторые делают простые преобразования (например, разворачивают условие if или переставляют инструкции, что бы запутать деобсфукаторы). Добавляя инструкции в код, они замедляют работу приложения. Также, иногда абсолютно не ведомо, что именно они там добавили. Может статистику считают, а может биткоины генерят. Если Вам страшно за свой код - удалите его с жесткого диска, сам диск сожгите. Так скорее всего никто никогда его не увидет и не сможет "повторно использовать". Менее параноидальный режим - использовать языки, которые меньше подвержены простому декомпилированию - С/С++ (только не CLI).

Ответ 3



De4dot не восстанавливает имена локальных переменных Их и без обфускации не восстановить. А вот структуру кода нормально восстанавливает. Это же логично? Еще восстанавливает имена параметров публичных функций. Они являются частью интерфейса для возможности вызова по имени. Возможно, какой-нибудь обфускатор и решит их вычистить. internal и private функций я не нашел в восстановленном с помощью De4dot файле. Возможно, какой-то оптимизатор их просто удалил как неиспользуемые. Однако если приватная функция вызывается публичной, то ее можно обнаружить и распознать структуру . Всё, что может найти jit-компилятор, может найти и декомпилятор. А если не может найти jit, то этот код бесполезен. Возможно, можно запутать декомпилятор кодом, генерируемым компилятором при использовании различных фич C#. Например, вызов по именам параметров, создающий локальные managed-ссылки на переменные, использование iterator function, async-await, приводящих к генерации goto, невалидных для шарповского кода, а также fault-блоков. Необходимость восстановления изначальных конструкций из этого поднимет требования к декомпилятору, но я не думаю, что обфускаторы на такое способны. Это скорее требование к самому коду. Да и декомпиляторы-то развиваются. Однажды случится так, что прошлая версия не могла восстановить код, а новая уже может.

Как понимается else if в C?

#c #if


До этого немного учил Python (там "или если" такого не было)
Сейчас учу C, читаю книгу и в примере написано else if - что это?

...
if (c==...)
  state = OUT;
else if (state == OUT){
  state = IN;
...


UPD:

...
while ((c = getchar()) != EOF){
  ++nc;
  if (c=='\n')
    ++nl;
  if(c==' ' || c== '\n' || c=='\t')
    state = OUT;
  else if(state==OUT){
    state = IN;
    ++nw;
  }
}

    


Ответы

Ответ 1



С одной стороны, вы можете смотреть на эту конструкцию, как на набор последовательно проверяемых условий: if (cond1) // выполняется cond1? { code1; // да -> выполняем code1 } else if (cond2) // нет? проверяем дальше: выполняется cond2? { code2; // да -> выполняем code2 } else if (cond3) // нет? проверяем дальше: выполняется cond3? { code3; // да -> выполняем code3 } else { code4; // все проверки не прошли - выполняем code4 } То есть это есть некий аналог switch. С другой стороны, в этой конструкции используется то, что else относится к ближайшему if, а значит, if после else — просто содержимое else-клаузы (которую можно для ясности отделить фигурными скобками): if (cond1) { code1; } else { if (cond2) { code2; } else { if (cond3) { code3; } else { code4; } } } Таким образом, мы остаёмся в пределах привычного if с двумя вариантами. Хотя так обычно не пишут, чтобы не плодить уровни вложенности. Обновление: Давайте разберём актуальный код: while ((c = getchar()) != EOF) { // считать следующий символ и проверить // не кончился ли stdin ++nc; // увеличить счётчик символов if (c=='\n') // если строка закончилась, ++nl; // увеличить счётчик строк if(c==' ' || c== '\n' || c=='\t') // если текущий символ -- пробел, state = OUT; // перейти в состояние "между словами" else if(state==OUT){ // иначе текущий символ не пробел, и // если мы были в состоянии "между словами" state = IN; // то перейти в состояние "в слове" ++nw; // и увеличить счётчик слов } } Судя по всему, это утилита wc?

Ответ 2



Так понятней? if( c == 1 ) { state = OUT; } else { if( state == OUT ) { state = IN; } }

Посоветуйте CMS для сайта [закрыт]

#cms


        
             
                
                    
                        
                            Закрыт. Этот вопрос не по теме. Ответы на него в данный
момент не принимаются.
                            
                        
                    
                
                            
                                
                
                        
                            
                        
                    
                        
                            Хотите улучшить этот вопрос? Переформулируйте вопрос,
чтобы он соответствовал тематике «Stack Overflow на русском».
                        
                        Закрыт 4 года назад.
                                                                                
           
                
        
Добрый день. Посоветуйте самую простую CMS.

Основные требования:


Размещать статью, возможность прикреплять файл к ней. Ограничивать доступ к файлам.
Только зарегистрированные могут скачать.
Регистрация, авторизация.
Меню сверху, может иметь много категорий.
Поиск по статьям.
Несложна в редактировании кода.
Бесплатная.


Спасибо!
    


Ответы

Ответ 1



Drupal https://www.drupal.org/ Легко настраивается, русифицируется. Огромное количество существующих бесплатных модулей и бесплатных тем оформления. Описанный Вами функционал можно реализовать без редактирования кода. Дружелюбное русскоязычное сообщество, http://www.drupal.ru/ Практически на любой каприз можно найти статью или даже видео инструкцию из серии "как сделать... как использовать..." CMS очень популярна. Друпалу под силу любая задача, разве что в магазин за пивом его послать нельзя. Из минусов как и у всех CMS прожорливость, но она решается кешированием. Для редактирования кода принято создавать отдельные модули с понятной друпалу структурой (править существующие самостоятельно - плохая идея в плане обновления новых версий движка и модулей). Но структура у модулей простая, на ее изучение уйдет минут 15, за то в коде порядок.

Ответ 2



Думаю, что подойдет WordPress. Размещать статью, возможность прикреплять файл к ней. Есть. Ограничивать доступ к файлам. Только зарегистрированные могут скачать. Наверняка можно сделать с помощью плагинов, коих огромное количество. Регистрация, авторизация. Есть. Меню сверху, может иметь много категорий. Темы настраиваются, раньше это было даже в теме по умолчанию. В последних версиях тема по умолчанию изменилась, вроде категории стали размещаться слева, но тем для WordPress написано такое количество, что по этому поводу тоже можно не беспокоиться. Поиск по статьям. Есть. Несложна в редактировании кода. Есть визуальный редактор и редактор HTML. Бесплатная. Да. Хотя есть платные плагины и темы.

Python2.7 ускорение работы кода, сложение огромных 2хмерных массивов

#python #оптимизация #python_2x


Есть два двумерных массива (например, ndarray):  


3000х4000 (12 000 000 элементов) - 2,5D карта высот - назовем Массив1  
100Х100 (10 000 элементов) - форма фрезы - назовем Массив2


Задача: нужно обойти "карту высот" "фрезой" и рассчитать 3й массив "оставшийся недорез"
для каждого пикселя из Массива1.

Проблема в том, что получается 3000Х4000Х100Х100=120 000 000 000 точек, и над каждой
нужно провести одну операцию вычитания, одну операцию сравнения на меньше, и несколько
операций записи.

Python 2.7 делает это ооочень медленно(на моем компе рассчитывает около 14 часов)

Подскажите, пожалуйста, как можно ускорить работу python скрипта?

Используемый алгоритм простой:

Цикл X по СтрокамМатрицы1: #3000
  Цикл Y по СтрокамМатрицы1: #4000
    Цикл N по СтрокамМатрицы2: #100
      Цикл M по СтрокамМатрицы2: #100
        ВремТочка = матр1[X+N,Y+M] - матр2[N,M]
        Если Матр3[X+N,Y+M] > ВремТочка:
          Матр3[X+N,Y+M] = ВремТочка


В реальности есть еще несколько дополнительных операций, но на суть это не влияет.

Вот используемый код:

 def get_rmf_map_tool(self,offset_image,tool_roughing,previous_offset,pixelstep_roughing):

        #Dictionary faster then array
        map_tool1 = {}  #numpy.zeros((self.w, self.h), numpy.float32) - self.image.min()
        y = x = 0   #init y,x for speed

        ts_roughing = tool_roughing.shape[0]

        max_line,max_pix = self.get_im_maxmin(self.w, self.h, ts_roughing)

        jrange = self.mxrange(self.row_mill, max_line, pixelstep_roughing)
        irange = self.mxrange(self.row_mill, max_pix)
        ln = max_line

        if prn_detal > 0: print "(Previous tool shape: {0} pixels, max line: {1},
max pixel: {2} )".format(ts_roughing,max_line,max_pix)

        trange = xrange(0,ts_roughing)

        for lin in jrange:    #lines
            progress(lin, ln)
            for pix in irange:    #pixels

                if self.row_mill:
                    y,x = lin,pix
                else:
                    x,y = lin,pix

                m1 = offset_image[y:y+ts_roughing, x:x+ts_roughing]
                hhh1 = (m1 - tool_roughing).max() + previous_offset

                for i in trange:    #lines tool
                    for j in trange:    #pixels tool

                        t = tool_roughing[i,j]
                        if isinf(t): continue

                        ty = i+y
                        tx = j+x
                        # self.image[ty,tx] <= hhh1 !!! t >= 0
                        dt = -self.image[ty,tx] + hhh1 + t
                        #dt = round(dt,16)

                        if dt < -epsilon and prn_detal > -1: print(" delta < -0.00001
",ty,tx,dt,self.image[ty,tx], hhh1, t)
                        if dt < .0: dt = .0

                        try:
                            if map_tool1[ty,tx] > dt:   #finde MAX for this pixel
                                map_tool1[ty,tx] = dt
                        except KeyError:
                            map_tool1[ty,tx] = dt

        if prn_detal > 0: print "(End make map tool1. Map len: {0} pixels. End at
{1})".format(len(map_tool1),datetime.now())
        if len(map_tool1) == 0 and prn_detal > -1: print "(WARNING! Map tool1 len:
{0}! )".format(len(map_tool1))


Принимаются любые предложения: ассемблер, ctypes, cython, средствами графического
процессора, OpenGL, Numpy, CUDA, ... Желательно с примером.
    


Ответы

Ответ 1



Увы, если ничего принципиально не менять в алгоритме, то разве что средствами графического процессора. На таких данных, пишите вы для процессора хоть на ассемблере, быстро не получится. Вот пример, чтоб не быть голословным: int main() { int i, j, k, l; long z = 0; for (i = 0; i < 300; ++i) for (j = 0; j < 4000; ++j) for (k = 0; k < 100; ++k) for (l = 0; l < 100; ++l) z++; } Как вы видите, я первый параметр уменьшил в 10 раз (ну допустим вы распараллелите на гипотетические 10 ядер), и вот, что получилось на не самом слабом компьютере: $ gcc test.c -o test $ time ./test ./test 31,72s user 0,00s system 99% cpu 31,728 total То есть почти 32 секунды, и это на чистом C с минимумом операций. Ну, будет, допустим, 20 секунд на самом современном процессоре, вряд ли это можно назвать быстро. Обновление: написал вашу логику на Cython: import numpy as np cimport numpy as np def calc( np.ndarray[np.double_t, ndim=2] A, np.ndarray[np.double_t, ndim=2] B, np.ndarray[np.double_t, ndim=2] C): cdef int N1 = A.shape[0] cdef int M1 = A.shape[1] cdef int N2 = B.shape[0] cdef int M2 = B.shape[1] cdef int i, j, k, l cdef double tp if N1 != C.shape[0] or M1 != C.shape[1]: raise ValueError('Array dimensions mismatch') for k in range(N2): for l in range(M2): for i in range(N1 - N2): for j in range(M1 - M2): tp = A[i + k, j + l] - B[k, l] if C[i + k, j + l] > tp: C[i + k, j + l] = tp Тестовый код (опять в 10 раз меньше данных, чтоб не ждать долго): import numpy as np import calc N, M = 300, 4000 n, m = 100, 100 A = np.random.random((N, M)) B = np.random.random((n, m)) C = np.random.random((N, M)) calc.calc(A, B, C) Вот пример запуска: $ time python2 test.py python2 test.py 36,68s user 0,05s system 99% cpu 36,734 total То есть ненамного дольше, чем на чистом C. На полных данных точно укладывается в ваше время. Обновление 2: ради интереса запустил на полных данных (массив размера 3000x4000), и получил следующий результат: $ time python2 test.py python2 test.py 1572,55s user 2,11s system 99% cpu 26:16,10 total В 30 минут уложились, но, конечно, получилось не так быстро, как хотелось бы. Предполагаю, это из-за того, что данные перестали помещаться в кэш. Скорее всего, если разбить большой массив на 10 меньших (которые будут попадать в кэш) и последовательно обработать их, получится гораздо быстрее. Можете попробовать сами, в обработке таких массивов будет пара тонких моментов, так что в рамках ответа на вопрос мне такой код писать лень.

Доступ к ресурсу с приоритетами

#c #многопоточность


День добрый.
Есть некоторый разделяемый ресурс с операциями чтения/записи. Известно что операций
чтения гораздо больше, чем записи.
Как организовать доступ к такому объекту? 
Понятно, что можно просто использовать семафор, и блочить на каждый поток ресурс,
вне зависимости чтение это или запись.
    


Ответы

Ответ 1



Может, вам нужен Readers–writer lock? Множество потоков могут читать Только один поток может писать Функции pthread: pthread_rwlock_init() pthread_rwlock_rdlock() pthread_rwlock_wrlock() pthread_rwlock_unlock() Winapi - SRW Locks

Ответ 2



Если пишите под Unix, то можно использовать блокировку чтения-записи pthread_rwlock. Она работает следующим образом : захватить блокировку на чтение и "мониторить" ресурс без модификации данных смогут одновременно N потоков. Если же какой-либо из потоков захватывает блокировку на запись, то продолжить работу этот поток сможет тогда, когда не захвачено ни одной блокировки на чтение (читателей у ресурса в текущий момент нет). Пока поток эксклюзивно удерживает блокировку на запись, все остальные читатели и писатели ждут. Обычно, потоки-писатели находятся в приоритете, т.е. если какой-то из потоков ждет возможности записи, доступ новых читателей к ресурсу блокируется (чтобы поток-писатель не ожидал бесконечно) и они ждут, пока отработает поток-писатель. В некоторых реализациях эту приоритетность по идее можно менять. Если же Вы пишите под Windows, то, возможно, стоит обратить внимание на shared_mutex.

Тестирование слоя валидации данных

#c_sharp #visual_studio #entity_framework #юнит_тесты


Люди, подскажите хорошее решение. Имеется некий слой валидации данных, бизнес логики
приложения и слой работы с БД. Есть правила накладывающие ограничения (например у некоторых
сущностей есть 2 идентификатора [Guid и string определенной длины] и должно контролироваться
отсутствие их дублирования с помощью валидации). При всем этом, при написании тестов
возникает кейс что мы тестируем работу слоя валидации и нужно что бы валидация не прошла
(т.к. в базе такой объект уже существует), либо наоборот прошла так как такого объекта
еще нет. И тут возникает проблема потому что мы не знаем что есть а чего нет в тестовой
базе. Возможный вариант решения это заранее наполнить базу некими сущностями и постоянно
работать с ними, но такой подход не нравится тем что при написании теста приходится
помнить что у нас есть в базе (да и тем более в других тестах могу создаваться новые
сущности), а хочется что бы мы могли в каждом тесте создать N удобных для этого теста
объектов и работать с ними. Но такой подход с обычной базой невозможен так как единственное
решение которое я вижу, это нужно будет чистить базу в каждом тесте а это не быстро
во всяком случае. Что приходит в голову это создать мок объекты работы с базой которые
можно будет чистить в каждом тесте или создавать заново но это не кажется изящным решением.
Собственно как решить проблему изящно ?
PS. Язык C# тесты встроенные в visual studio, использую entity-framework 
    


Ответы

Ответ 1



Ваши юнит-тесты вообще не должны подключаться к базе данных. Вы должны тестировать только ваш класс, отвечающий за валидацию, все внешние зависимости этого класса надо заменить моками. У вас должен быть мок, который будет притворяться, что он подключается к базе данных, но на деле никуда не подключаться, а просто возвращать подходящие для тестирования значения. На примере одного теста. Скажем вы проверяете, что в базе нет двух элементов с одинаковым id. Тогда тест должен выглядеть примерно так: создаете мок класса для доступа к базе данных настраиваете нужный метод этого мока так, чтобы он возвращал заведомо неверные данные передаете этот мок валидатору и убеждаетесь, что валидация не прошла Код примерно такой (в примере используется nunit и moq): [Test] public void Test1() { // arrange var dbRepositoryMock = new Mock(); dbRepositoryMock.Setup(x => x.GetItems()).Returns(new [] {new Item(){ Id = 1}, new Item(){ Id = 1}}); var validator = new Validator(); // action var validationResult = validator.ValidateItemsUnique(dbRepositoryMock.Object); // assert Assert.IsFalse(validationResult); } То есть идея вот в чем: вы создаете реальный экземпляр ТОЛЬКО для тестируемого класса. В нашем случае тестируемый класс - валидатор. Для всех зависимостей вы создаете моки, и настраиваете у этих моков ТОЛЬКО те методы, которые используются тестируемым функционалом, все остальные просто игнорируете. Например, у вашего репозитория может быть еще 20 методов, возвращающих разные сущности из базы данных, но если вы проверяете уникальность Item'ов, вы настраиваете возвращаемое значение только метода GetItems(), а все остальные методы просто игнорируете. Про подключение к базе данных вообще забудьте, ваши юнит тесты должны выполняться без этого. Если вам сложно написать код в таком стиле - без реального подключения к базе данных, значит он плохо приспособлен для юнит-тестирования, и надо выполнять его рефакторинг. Ваша попытка написать юнит-тесты с подключением к реальной бд довольно типичная ошибка для начинающих писать юнит-тесты. Я тоже пытался делать так и видел как то же самое пытаются сделать другие. Эта ошибка указывает на то, что вы не до конца понимаете смысл юнит-тестирования и вам стоит потратить время на чтение какой нибудь книги по этой теме. "Разработка через тестирование" Кента Бека будет отличным вариантом.

Ответ 2



Строго говоря, вы пишете не юнит тесты, а, скорее, интеграционные тесты. Если не ограничиваться ответом "тесты на базе это плохо, постарайтесь по возможности избегать этого" - то проще всего решить проблему чистки базы в интеграционных тестах отменой транзакции на каждом тесте: один раз создавать чистую базу при старте тестов (указанием DropCreateDatabaseAlways, или вручную, по статическому флагу) создавать новый TransactionScope в TestInitialize диспоузить этот TransactionScope в TestCleanup, без вызова Complete Работать будет не мгновенно, накладные расходы будут порядка 100-200 ms на тест, но для существующего (уже написанного без тестов) кода это самый быстрый вариант. Eсли вы планируете рефакторить код в сторону лучшей тестируемости моками - лучше если к моменту рефакторинга у вас будут готовые тесты на тот код, который уже есть, пусть даже эти тесты будут медленными и будут делать реальные запросы к базе. Рефакторить непокрытый тестами код может только Чак. Для всех остальных это черевато затягиванием сроков, толпами новых багов и "в гробу я видал ваши тесты и рефакторинг" от ближайшего вверх по иерархии нетехнического начальника. Кстати, ваш способ валидации ненадежен. Ничто не помешает гому потоку влезть в базу между проверкой с результатом "все ок" и вставить туда дубликат. Такие проверки все равно надо дублировать констрейнтами на уровне базы.

Один экземпляр класса

#java


Как эффективно реализовать создание только одного экземпляра класса? Необходимо чтобы
создавать можно было только один объект. Вот что получилось у меня 

class Loader{
    private static int id = 0;
     static Loader newLoader(){
            if(id == 0){
                id++;
                return new Loader();
            }
            else
                return null;
    }
    private Loader(){

    }
}


Насколько это правильно? И Можно ли сделать так, чтобы метод newLoader() не возвращал
null в случае наличия уже созданного объекта, а присваивал ссылке тот же объект? То
есть  чтобы ссылка на объект не терялась. 
    


Ответы

Ответ 1



Вы "изобрели" singleton, в интернете полно примеров реализации. Самый простой пример: public class Singleton { private static Singleton instance; public static synchronized Singleton getInstance() { if (instance == null) instance = new Singleton(); return instance; } }

Ответ 2



На мой взгляд самый удобный способ в java создать Singleton: public class Singleton { // приватный конструктор - из вне нельзя будет создать объект. private Singleton() {} public static Singleton getInstance() { return SingletonHolder.HOLDER_INSTANCE; } static class SingletonHolder { private static final Singleton HOLDER_INSTANCE = new Singleton(); } } Советую прочитать статью «Правильный Singleton в Java» на Хабрахабре.

Ответ 3



если говорить о синглтонах то есть вот такая реализация "из коробки"/ by classloader, хочу отметить что в отличие от примера выше тут не нужна синхронизация: public enum Singleton { INSTANCE; public void someMethod(){ } } но все же лучше использовать Dependency Injection

Ответ 4



Физическое ограничение в один экземпляр класса - это всегда плохо. Рано или поздно требуется второй с категорически иным наполнением, и тут начинаются пляски с выставлением новых данных, использованием класса, и возвратом всего на место. Хорошим тоном считается создать ровно один экземпляр класса и передавать его в программе между другими объектами (если это необходимо). В случае сложной структуры в этом может помочь DI-контейнер, задача которого заключается как раз в том, чтобы создавать сервисы, держать в себе ссылки на них, автоматом подставлять их в конструкторы свежесоздающихся сервисов и разрешать цепочки зависимостей. В случае, если созданием ваших сервисов занимается контейнер, вы можете быть уверены что внутри контейнера хранится только один объект вашего сервиса. Для Java можно использовать Google Guice, например.

Ответ 5



Вообще, singleton я считаю здесь не нужен! Каждый вызов getInstance() занимает наносекунды на проверку условия if(...) Считаю, что данный вариант оптимален, ибо быстрее чем сразу не бывает: class Cat { private static Cat cat = new Cat(); private Cat() { } public void voice() { System.out.println("Meow :3"); } public static Cat getInstance() { return cat; } } Замечание: Отражения в Java в любом случае позволяют обойти всё, что вы придумаете для создания "единственного" экземпляра, и создать множество других ;)

Ответ 6



Я бы наверное так сделал: class Loader{ static Loader a = new Loader(); public Loader(){ return a; } }

Подсветка закрывающихся тегов (Highlighting matching tags Sublime Text)

#sublime_text


Возможно ли кастомизировать подстветку закрывающихся тегов в Sublime Text 3 подобно
тому, как на скриншоте ниже(Так реализовано в Brackets)?.
Есть плагин для этих целей BracketHighlighter (https://github.com/facelessuser/BracketHighlighter),
но перебрав имеющиеся конфиги, не 


    


Ответы

Ответ 1



Подчерк, а не подсветка тегов и скобок в Sublime Text 3 реализовывается без плагинов. Для начала на всякий случай кликаем на Preferences → Settings - User , в открывшийся файл между {} добавляем следующие строки: "match_brackets": true, "match_brackets_angle": true, "match_brackets_square": true, "match_brackets_braces": true, "match_brackets_content":true, "match_tags": true, Сохраняем. В Sublime Text 3 всем этим параметрам кроме match_brackets_angle присвоено значение true, но мало ли, в последующих сборках могут и поменять на false. match_brackets — подчёркивание различных разновидностей скобок, match_tags — подчерк тегов. Далее открываем файл привычной цветовой схемы с расширением tm.Theme. В самом его начале находим примерно следующие строки ( значения цветов могут отличаться от приведённых в примере): lineHighlight lightslategray foreground #ffdab9 invisibles #BFBFBF selection dimgray Где-нибудь между ними до закрывающих тегов вставляем следующие теги: bracketContentsForeground yellow bracketContentsOptions underline bracketsForeground cyan bracketsOptions squiggly_underline tagsForeground lawngreen tagsOptions underline Пояснения: bracketContentsForeground — цвет подчёркивания любых скобок, между которыми расположена каретка. Между тегами вписывается цвет, лучше в формате HEX, чем X11, поскольку в Sublime Text могут возникнуть проблемы как минимум с отображением цветов aqua, fuchsia и lime. bracketContentsOptions — стиль подчёркивания скобок, между которыми расположена каретка. Значения: underline — подчерк прямой линией, stippled_underline — пунктирной, squiggly_underline — волнистой. По умолчанию underline. bracketsForeground — цвет подчёркивания скобок, когда рядом со скобками расположена каретка. Между тегами вписывается цвет. bracketsOptions — стиль подчёркивания скобок, рядом с которыми расположена каретка. Значения: underline — подчерк прямой линией, stippled_underline — пунктирной, squiggly_underline — волнистой. По умолчанию underline. tagsForeground — цвет подчёркивания тегов. Когда каретка находится внутри тега, подчёркивается как он сам, так и соответствующий ему открывающий/закрывающий тег. tagsOptions — стиль подчёркивания тегов. Значения: underline — подчерк прямой линией, stippled_underline — пунктирной, squiggly_underline — волнистой. По умолчанию stippled_underline . Мне этого вполне хватает. Спасибо.

Ответ 2



Лучше, чем так, воспользоваться плагином BracketHighlighter. Частая проблема — скобки и кавычки как в коде, так и gutter (полоса, где номера строк) подсвечиваются тем же цветом, что и текст. Чтобы её исправить, необходимо: Preferences → Package Settings → BracketHighlighter → Bracket Settings - User → в открывшийся файл вставляем следующий код → сохраняем файл. { "bracket_styles": { // This particular style is used to highlight // unmatched bracket pairs. It is a special // style. "unmatched": { "icon": "question", "color": "brackethighlighter.unmatched", "style": "highlight" }, // User defined region styles "curly": { "icon": "curly_bracket", "color": "brackethighlighter.curly", "style": "highlight" }, "round": { "icon": "round_bracket", "color": "brackethighlighter.round", "style": "outline" }, "square": { "icon": "square_bracket", "color": "brackethighlighter.square", "style": "outline" }, "angle": { "icon": "angle_bracket", "color": "brackethighlighter.angle", "style": "outline" }, "tag": { "icon": "tag", "color": "brackethighlighter.tag", "style": "outline" }, "single_quote": { "icon": "single_quote", "color": "brackethighlighter.quote", "style": "outline" }, "double_quote": { "icon": "double_quote", "color": "brackethighlighter.quote", "style": "outline" }, "regex": { "icon": "regex", "color": "brackethighlighter.quote", "style": "outline" } } } В файл своей цветовой схемы с расширением tmTheme (если не знаете, как его открыть, см. здесь в самом начале) где-нибудь между тегами вставляем следующие строки: name Unmatched scope brackethighlighter.unmatched settings foreground #FD971F name BracketHighlighter: Curly scope brackethighlighter.curly settings foreground #FF0000 name BracketHighlighter: Round scope brackethighlighter.round settings foreground lightblue name BracketHighlighter: Square scope brackethighlighter.square settings foreground pink name BracketHighlighter: Angle scope brackethighlighter.angle settings foreground #FEFE22 name BracketHighlighter: Bracket Tag scope brackethighlighter.tag settings foreground violet name BracketHighlighter: Single Quote | Double Quote | Regex scope brackethighlighter.quote settings foreground palegreen Между тегами под foreground меняем цвета, как душе угодно. Лучше прописывать их в HEX, а не X11 colors, поскольку в Sublime Text 3 могут некорректно отображаться как минимум цвета aqua, fuchsia и lime. Скобки, кавычки и их выделения в тексте должны получиться разноцветными:

Переменная в имени другой

#c_sharp #wpf


Есть несколько textbox'ов: TextBoxTovar1, TextBoxTovar2 и т.д. Хочу пробежать по
ним циклом:

for (int i = 0; i < count; i++)
{
    Fill(TextBoxTovar[i].Text);
}


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


Ответы

Ответ 1



В WinForms контролы на форме можно искать по имени: for (int i = 1; i <= count; i++) { Fill(((TextBox)Controls["TextBoxTovar" + i]).Text); } будут найдены только тектбоксы, лежащие непосредственно на форме. Если нужно искать во другом контейнере (например, панели) - то нужно использовать свойство Controls этого контейнера, а не свойство формы. Для WPF аналог Controls[name] это метод FindName у окна или любого другого контейнера: for (int i = 1; i <= count; i++) { Fill(((TextBox)FindName("TextBoxTovar" + i)).Text); } FindName работает рекурсивно, так что он найдет не только элементы, лежащие на самой форме, но и элементы во вложенных контейнерах.

Ответ 2



Очень странный вопрос. Без костыля тут не обойтись думаю. Но можно и при помощи Linq: foreach (TextBox tb in Controls.Cast().Where(x => x is TextBox).Select(x=>x as TextBox)){ // do something } Данный код переберет все TextBoxв форме. Надеюсь поможет. P.S если выберите этот вариант поиска, смогу более подробно рассказать/объяснить что к чему.

python загрузка файлов vk

#python #вконтакте #vkontakte_api


Подключил VK API. Необходимо сделать отправку файлов на сервер как о этом рассказано
на этой странице - http://vk.com/dev/upload_files
P.S. Загрузка файлов на стену пользователя

import vk
from time import sleep
import sys
import urllib.request
import urllib.parse
import base64
import requests

vkapi = vk.API(access_token='token', app_id='id')
sleep(0.5)

data = vkapi.photos.getWallUploadServer(user_id="72374405")
DATA_USER_ID = data['user_id']
DATA_ALBUM_ID = data['album_id']
DATA_UPLOAD_URL = data['upload_url']

#with open("1.jpg", "rb") as image_file:
    #fileD = base64.b64encode(image_file.read())


#files = {'1.jpg': open('1.jpg', 'rb')}
#r = requests.post(DATA_UPLOAD_URL, files=files)
#r.status_code == requests.codes.ok
#print(r)
#html = r.read().decode("utf-8")

#dataP = '1.jpg'
dataP = "photo=" + dataP#.encode("ASCII")
response = urllib.request.urlopen(DATA_UPLOAD_URL,dataP)
html = response.read().decode("utf-8")
print (html)


решеткой помечено то, что пробовал но не сработало, либо не подошло.

Вроде как корректно отработался вариант с 

files = {'1.jpg': open('1.jpg', 'rb')}
r = requests.post(DATA_UPLOAD_URL, files=files)
r.status_code == requests.codes.ok
print(r)
#html = r.read().decode("utf-8")


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

В случае успешного завершения кода выхлоп таков: 

{"server":622624,"photo":"[]","hash":"8112ae8847b27fb1cdf678d3d168e6ae"}


То есть загрузка изображения провальная.

Может кто-либо смог или и так знает как загрузить файл на сервер ВК через POST на
Python3. Поделитесь опытом, советом, замечанием. Если что-то в коде непонятно - пишите;
отвечу.
    


Ответы

Ответ 1



Вот мой вариант размещения фотографии на стене сообщества от имени сообщества. Реализован алгоритм, описанный в официальной документации: # Импортируем необходимые модули import vk import requests # Задаём идентификатор группы, токен доступа, картинку и её описание group_id = 'my_group_id' access_token = 'my_access_token' filename = 'image.jpg' caption = 'Some text' # Авторизуемся в VK session = vk.Session(access_token=access_token) vk_api = vk.API(session) # Получаем адрес сервера для загрузки картинки upload_url = vk_api.photos.getWallUploadServer(group_id=group_id)['upload_url'] # Формируем данные параметров для сохранения картинки на сервере request = requests.post(upload_url, files={'photo': open(filename, "rb")}) params = {'server': request.json()['server'], 'photo': request.json()['photo'], 'hash': request.json()['hash'], 'group_id': group_id} # Сохраняем картинку на сервере и получаем её идентификатор photo_id = vk_api.photos.saveWallPhoto(**params)[0]['id'] # Формируем параметры для размещения картинки в группе и публикуем её params = {'attachments': photo_id, 'message': caption, 'owner_id': '-' + group_id, 'from_group': '1'} vk_api.wall.post(**params)

Ответ 2



Есть библиотека vk_api, у нее есть вспомогательный класс для загрузки файлов VkUpload, а у него есть нужный метод photo_wall. Добавляю пример использования (ссылка на полный скрипт с картинками): import vk_api from vk_api import VkUpload login, password = '', '' # Авторизация vk_session = vk_api.VkApi(login, password) vk_session.auth() upload = VkUpload(vk_session) # Для загрузки изображений # Загрузка картинок на сервера вк и получение их id photos = ['1.jpg', '2.jpg'] photo_list = upload.photo_wall(photos) attachment = ','.join('photo{owner_id}_{id}'.format(**item) for item in photo_list) # Добавление записи на стену vk_session.method("wall.post", { 'owner_id': None, # Посылаем себе на стену 'message': 'Test!', 'attachment': attachment, }) Вот так будет выглядеть запись на стене:

Ответ 3



Как-то разобрался :D import vk from time import sleep import sys import urllib.request import urllib.parse import base64 import requests import json vkapi = vk.API(access_token='token', app_id='app_id') sleep(0.5) data = vkapi.photos.getWallUploadServer(user_id="72374405") DATA_USER_ID = data['user_id'] DATA_ALBUM_ID = data['album_id'] DATA_UPLOAD_URL = data['upload_url'] r = requests.post(DATA_UPLOAD_URL, files={'photo': open('1.jpg',"rb")}) r.status_code == requests.codes.ok params = {'server': r.json()['server'], 'photo': r.json()['photo'], 'hash': r.json()['hash']} wallphoto = vkapi.photos.saveWallPhoto(**params) #attachments.append(wallphoto[0]['id']) photoID = wallphoto[0]['id'] params = {'attachments': 'photo' + '72374405_' + str(photoID), 'message': 'Test'} params['owner_id'] = '72374405' print(params) vkapi.wall.post(**params) Позже уже буду разбираться во всем этом коде и делать его более читаемым. Главное что он сейчас работает :)