Страницы

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

среда, 10 июля 2019 г.

WCF ServiceHost передача параметра

Имеется следующая структура:
public class Starter { public void Start() { var host = new ServiceHost(typeof(ServiceExchange), new Uri(uri)); host.AddServiceEndpoint(typeof(IServiceExchange)), new BasicHttpBinding(), ""); } }
ServiceExchange описан так:
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single)]
Есть ли какой-нибудь способ создать объект(например список) в методе Start и передать его в ServiceExchange, который является контрактом, доступным клиентам? При этом, чтобы этот список мог обновляться как изнутри ServiceExchange, так и снаружи, в классе Starter


Ответ

У конструктора ServiceHost есть перегрузка, которая позволяет передать уже готовый экземпляр сервиса:
var someList = new List(); var service = new ServiceExchange(someList); var host = new ServiceHost(service, new Uri(uri));
Но поскольку вы собираетесь изменять список как внутри сервиса, так и снаружи, могут возникнуть проблемы с синхронизацией. Я бы порекомендовал инкапсулировать работу со списком в некий класс, в котором будут все необходимые методы, а также синхронизация доступа к списку (поскольку изменяться он будет все равно из разных потоков -- один поток сервиса и как минимум один поток приложения). А затем использовать этот класс из нужных мест.

Вставить в контейнер html+text

var str='Hello World'; var tooltipHtml = '' + str + ''; $('#tooltip').html(tooltipHtml);
Результатом в контейнере #tooltip будет слово Hello World Но если
var str='

Hello World

';
Результатом будет Hello World, а нужно

Hello World

Это пример, теги будут разные в разной ситуации, как наполнять некий контейнер( в данном примере tooltip) и html и text одновременно? Может как-то экранировать все теги в str?
Второй вариант который может встречаться это когда
var str='Hello World'; var tooltipHtml = '' + str + 'Часть недоступна'; $('#tooltip').html(tooltipHtml);


Ответ

Попробуйте так
var str='

Hello World

'; var container = $(''); container.text(str); $('#tooltip').html(container);

Видео (WebView) в полноэкранном режиме не до конца масштабируется под размер экрана

Пишу клиент для сайта. Есть WebView в который грузится контент, в том числе видео. Реализовал чтобы работал полноэкранный режим, но видео разворачивается не во всю ширину экрана. По бокам остается пространство. Прошу помочь советом, что сделал не так или куда смотреть.





public class DescriptionActivity extends Activity {
ProgressDialog mProgressDialog; private WebChromeClient.CustomViewCallback mFullscreenViewCallback; private FrameLayout mFullScreenContainer; private View mFullScreenView; private WebView mWebView;
private static final int SUCCESS = 1; private static final int NETWORK_ERROR = 2; private static final int ERROR = 3;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_description);
mWebView = (WebView) findViewById(R.id.web_view); mFullScreenContainer = (FrameLayout) findViewById(R.id.fullscreen_container); mWebView.getSettings().setJavaScriptEnabled(true); mWebView.setWebChromeClient(mWebChromeClient);
mWebView.setScrollbarFadingEnabled(true); mWebView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY); mWebView.setPadding(0, 0, 0, 0);
WebSettings settings = mWebView.getSettings(); settings.setDefaultTextEncodingName("utf-8");
new getHtml().execute(); }
private class getHtml extends AsyncTask { Elements tfa; Elements title; Elements comments;
@Override protected void onPreExecute() { mProgressDialog = new ProgressDialog(DescriptionActivity.this); mProgressDialog.setMessage("Загрузка..."); mProgressDialog.setIndeterminate(false); mProgressDialog.show(); }
@Override protected Integer doInBackground(String... params) { try {
Uri urls = getIntent().getData(); String url = urls.toString();
Document doc = Jsoup.connect(url) .userAgent("Mozilla") .cookie("auth", "token") .timeout(10000) .get();
title = doc.select(".c1-post").select("span"); tfa = doc.select(".c1-post-data"); comments = doc.select(".content").select(".comments");
return SUCCESS; } catch (UnknownHostException e) { Log.e("Unknown Host Exception", "Network error", e); return NETWORK_ERROR; } catch (IOException e) { Log.e("IO Exception", "Failed to load HTML", e); return ERROR; } catch (Exception e) { Log.e("Exception", "An exception occured", e); return ERROR; }
}
@Override protected void onPostExecute(Integer result) {
if (result == 2) { Toast.makeText( getApplicationContext(), "Network connection error. Check your internet connection and try again.", Toast.LENGTH_LONG).show(); } else if (result == 3) { Toast.makeText(getApplicationContext(), "Unknown error. Failed to load.", Toast.LENGTH_LONG).show(); } else if (result == 1) {
String comqqq = Jsoup.clean(comments.toString(), Whitelist.basic());
mWebView.loadDataWithBaseURL("http://fratria.ru/", "" + "

" + title.html() + "

" + tfa.html() + comqqq, "text/html", "en_US", null); }
mProgressDialog.dismiss(); } }
@Override public void onResume() { super.onResume(); mWebView.onResume(); }
@Override public void onPause() { super.onPause(); mWebView.onPause(); }
private final WebChromeClient mWebChromeClient = new WebChromeClient() { @Override @SuppressWarnings("deprecation") public void onShowCustomView(View view, int requestedOrientation, CustomViewCallback callback) { onShowCustomView(view, callback); }
@Override public void onShowCustomView(View view, CustomViewCallback callback) { if (mFullScreenView != null) { callback.onCustomViewHidden(); return; }
mFullScreenView = view; mWebView.setVisibility(View.GONE);
mFullScreenContainer.setVisibility(View.VISIBLE); mFullScreenContainer.addView(view); mFullscreenViewCallback = callback; }
@Override public void onHideCustomView() { super.onHideCustomView(); if (mFullScreenView == null) { return; } mWebView.setVisibility(View.VISIBLE);
mFullScreenContainer.setVisibility(View.GONE);
mFullScreenContainer.removeView(mFullScreenView); mFullscreenViewCallback.onCustomViewHidden(); mFullScreenView = null; } };
}


Ответ

Ну для начала я бы посоветовал прятать статус бар
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
Тогда у видео будет достаточно высоты что бы при сохранении пропорций заполнить и ширину. Но если у экрана телефона соотношение сторон не соответствует таковому у видео, то тут уж без черных полос не обойдется...

Переменная не изменяет значение

Проблема заключается в том, что по идее переменная lowest должна изменять своё значение, как и highest (с ней всё получается), но почему то этого не происходит. Выставляю код вам на обозрение:
digits = [] sum = 0 lowest = 0 highest = 0
while True: digit = input('enter a number or Enter to finish: ') if digit == '': break Digit = int(digit) digits.append(Digit) sum += Digit if len(digits) == 0: lowest = Digit highest = Digit elif highest < Digit: highest = Digit elif lowest > Digit: lowest = Digit
print('numbers: ', digits) print('count =', len(digits), 'sum =', sum, 'lowest =', lowest, 'highest =', highest, 'mean =', sum/len(digits))
Вывод программы такой:
enter a number or Enter to finish: 43 enter a number or Enter to finish: 324 enter a number or Enter to finish: 2 enter a number or Enter to finish: 5 enter a number or Enter to finish: 65 enter a number or Enter to finish: 757 enter a number or Enter to finish: 33 enter a number or Enter to finish: 423 enter a number or Enter to finish: numbers: [43, 324, 2, 5, 65, 757, 33, 423] count = 8 sum = 1652 lowest = 0 highest = 757 mean = 206.5


Ответ

Условие if len(digits) == 0 у Вас не выполняется никогда, т.к. вы добавлете число еще ДО его проверки. Просто переместите digits.append(Digit) в конец цикла, и все заработает.
П.С. Если ввести отрицательное число - должно заработать и так)))
П.П.С. highest также определится неверно, если все числа - отрицательные.
Рабочий код:
digits = [] sum = 0 lowest = 0 highest = 0
while True: try: digit = input('enter a number or Enter to finish: ') except: break if digit == '': break Digit = int(digit) sum += Digit if len(digits) == 0: lowest = Digit highest = Digit elif highest < Digit: highest = Digit elif lowest > Digit: lowest = Digit digits.append(Digit)
print 'numbers: ', digits # print lowest, highest print 'count =', len(digits), 'sum =', sum, 'lowest =', lowest, 'highest =', highest, 'mean =', sum/len(digits)
Вывод консоли:
D:\Python>python test002.py enter a number or Enter to finish: 43 enter a number or Enter to finish: 324 enter a number or Enter to finish: 2 enter a number or Enter to finish: 5 enter a number or Enter to finish: 65 enter a number or Enter to finish: 757 enter a number or Enter to finish: 33 enter a number or Enter to finish: 423 enter a number or Enter to finish: numbers: [43, 324, 2, 5, 65, 757, 33, 423] count = 8 sum = 1652 lowest = 2 highest = 757 mean = 206

Перенаправление stdout и stderr и на экран и в файл

Как в начале скрипта перенаправить вывод в файл и на экран одновременно?


Ответ

написанное ниже справедливо, насколько я знаю, лишь для «продвинутых» оболочек типа gnu/bash и zsh

для перенаправления всего, что будут выдавать команды, выполняющиеся внутри скрипта, в файл (вдобавок к выводу на терминал), можно использовать команду exec в комплекте с программой tee
если требуется записывать в файл file только то, что команды скрипта будут выдавать в stdout, можно написать так:
exec > >(tee file) command1 command2
если же требуется записывать в файл и то, что отправляется в stderr, то надо добавить перенаправление 2>&1
exec > >(tee file) 2>&1 command1 command2

дополнение по поводу просто вывода в файл обоих потоков полностью posix-совместимым образом
и stdout и stderr, в которые выведут информацию команды, будут записаны в file
exec >file 2>&1 command1 command2
а так file будет дополнен (а не перезаписан, как в предыдущем примере):
exec >>file 2>&1 command1 command2

Конструктор ошибок javascript

Подскажите, как более правильно создавать ошибки в Javascript из прототипа так, чтобы с ними удобнее было работать. Например, если я создаю ошибку таким образом, то выбрасывая исключение, нужно вызывать constructor, опять же, проверяя на принадлежность ошибки к моему классу, снова приходится дергать constructor
var SpecificError = Object.create(Error.prototype); SpecificError.constructor = function(message) { this.name = 'Specific Error'; this.message = message; this.stack = (new Error).stack; return this; }; SpecificError.constructor.prototype = SpecificError;
JSFiddle


Ответ

Судя по всему здесь хотелось использовать наследование. Для этого нужно было сделать SpecificError функцией конструктором
function SpecificError(message){ ... }
Внутри его вызвать конструктор базового класса, в данном случае Error
Error.call(this,message);
а далее установить прототип
SpecificError.prototype = Object.create(Error.prototype);
Но, наследоваться от Error не так просто, так как его конструктор не оперирует с this и следовательно не добавит в него автоматом нужные свойства. Но, можно использовать решение из этого ответа, сохранить полученный экземпляр Error, назначить ему name и использовать его stack
function SpecificError(message, name) { var err = Error.call(this, message); err.name = this.name = (name || 'SpecificError'); err.message = this.message = message; Object.defineProperty(this, 'stack', { get: function() { return err.stack; } }); }
Измененный пример из JSFiddle
function SpecificError(message, name) { var err = Error.call(this, message); err.name = this.name = (name || 'SpecificError'); err.message = this.message = message; Object.defineProperty(this, 'stack', { get: function() { return err.stack; } }); } SpecificError.prototype = Object.create(Error.prototype); function OtherError(message) { SpecificError.call(this, message, 'OtherError'); } OtherError.prototype = Object.create(SpecificError.prototype); try { throw new OtherError('Very specific error'); } catch (e) { if (e instanceof OtherError) { console.log(e); console.log(e.stack); } else throw e; }

Как автоматически настраивать высоту child элемента в ExpandableListView

Есть ExpandableListView, который содержит группы и вложенные элементы групп. В каждом элементе группы содержится 2 текстовых поля (слева и справа). Бывает такое, что текст в текстовом поле вложенного элемента группы слишком большой, и он разбивается на 3 строки. После этого он не помещается в высоту элемента группы.
Как сделать так, чтобы высота элемента группы устанавливалась автоматически в зависимости от количества текста в первом текстовом поле? Разметка для child элемента

android:textSize="16sp" android:textColor="#000000" android:layout_weight="3" />
android:textSize="16sp" android:textColor="#000000" android:background="@drawable/backgroun_button_nazad" android:textIsSelectable="false" android:gravity="center" />


Ответ

Вам надо для текстового поля указать высоту равную wrap_content и для его контейнера-родителя указать высоту равную match_parent


Сохранение картинок из ссылок при парсинге Jsoup'ом

Вообщем есть идея сделать возможность скачивать нужную информацию на свой телефон и хранить ее, чтобы она была доступна даже без сети. Вообщем, как вижу это я: Скачиваю HTML страницу с помощью jsoup библиотеки и сохраняю ее в string. С помощью elements выбираю ссылки на картинки, а также с помощью тех же элементов даю примерный путь к сохранению картинки, к примеру "/stat/1.png" Так вот проблема в том, как скачать их и сохранить в папку с приложением по такому шаблону: путь к папке с приложением + "/stat/1.png" (то, что я получаю при парсинге). Как это можно реализовать? Помогите пожалуйста, никогда не сталкивался со скачиванием и сохранением просто


Ответ

Используйте отечественную разработку Universal Image Loader. После её настройки согласно инструкции по ссылке процесс загрузки будет выглядеть так:
String imageUri = "ТУТ_АДРЕС_КАРТИНКИ_В_ИНТЕРНЕТЕ"; imageLoader.loadImage(imageUri, new SimpleImageLoadingListener() { @Override public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) { // Можно пустым оставить и ничего тут не делать } });
Библиотека поместит загруженное изображение в кэш, и когда вам понадобится её отобразить вы сможете просто вызвать:
imageLoader.displayImage(imageUri, imageView);
чтобы из кэша установить вашу картинку в ImageView

Подобных библиотек множество. Из последних - fresco от лицоКниги.

Как добавить прозрачность в ListView? [закрыт]

Как добавить прозрачность в ListView?
Когда прокручиваю надо чтобы нижняя и верхняя граница была прозрачной. как увеличить height у этих двух вещей?


Ответ

Вам необходимо анимировать создаваемые элементы. Можно использовать подготовленную анимацию fade_in. Для это добавьте всего одну строчку кода в ваш адаптер.
view.startAnimation(AnimationUtils.loadAnimation(mContext, android.R.anim.fade_in));
До:

После:

Парсинг бинарного файла

Необходимо распарсить файл. Формат данных более-менее приемлимый: экспорт заявок, размер файлов 1-25 мб, в каждой строке до символа ':' тэг, после него данные, строки кончаются 0x0D 0x0A, заявки отделены 0x0C).
Читал бы построчно, но проблема в символах 0x00, которых понатыкано очень много и в разных местах и последовательностях (да и 0x0A 0x0D местами 10-20 подряд).
Поэтому файл пробую читать как бинарный, для проверки пишу содержимое в другой файл.
Под debug нет проблем, в конце чтения выставляются EOF и FAIL, в конце записи почему-то BAD
Под release данные пишутся, но в конце записи все флаги не выставлены, в конце файла многочисленные символы 0x00 (для Unicode при сколько-нибудь крупном файле, странно - для мелочи в 1-100 строк такое не происходит) или вообще мусор в разнобой (для multibyte).
В чём может быть проблема? Тестировал на исходном файле с экспортом заявок и на файле-тестовике, генерируемом PrepareForTestBinary. Пробовал включить исключения для потоков, но ничего интереснее ios_base::failbit set ; iostream:1 не выдаёт.
У меня MS VS2010
Командная строка компилятора под Release
/Zi /nologo /W3 /WX- /O2 /Oi /Oy- /GL /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /Gm- /EHsc /GS /Gy /fp:precise /Zc:wchar_t /Zc:forScope /Fp"Release\binread.pch" /Fa"Release\" /Fo"Release\" /Fd"Release\vc100.pdb" /Gd /analyze- /errorReport:queue
Командная строка компилятора под Debug
/ZI /nologo /W3 /WX- /Od /Oy- /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /Gm /EHsc /RTC1 /GS /fp:precise /Zc:wchar_t /Zc:forScope /Fp"Debug\binread.pch" /Fa"Debug\" /Fo"Debug\" /Fd"Debug\vc100.pdb" /Gd /analyze- /errorReport:queue
Игры с опциями ничего не дали.
Вот код:
#ifndef _UNICODE #define TCOUT std::cout #else #define TCOUT std::wcout
typedef std::basic_ios tios; typedef std::basic_ifstream tifstream; typedef std::basic_ofstream tofstream; typedef std::basic_string tstring;
//проверка флагов для потоков void fState(tios &fs) { TCOUT << _T("fail bad eof good
"); TCOUT << (fs.rdstate()&fs.failbit) << _T(" ; ") << (fs.rdstate()&fs.badbit) << _T(" ; ") << (fs.rdstate()&fs.eofbit) << _T(" ; ") << (fs.rdstate()&fs.goodbit) << endl; }
//Для тестирования генерируем исходный файл void PrepareForTestBinary(tstring PATH) { tofstream os; os.open (PATH, ios_base::binary ||ios_base::out); for (int i = 0; i<200000;i++) os << _T("0123456789") << '\0' << _T("ABCDEFGHIJ") << std::endl; os.close(); } // Читаем и пишем void TestBinary(tstring inPATH,tstring outPATH) { LONGLONG len; TCHAR * buffer; tifstream is; fState(is); is.open (inPATH, ios_base::binary ||ios_base::in ); fState(is); is.seekg (0, ios::end); len = is.tellg(); is.seekg (0, ios::beg); buffer = new TCHAR [len]; fState(is); is.read (buffer,len); fState(is); is.close(); tofstream os; fState(os); os.open (outPATH, ios_base::binary ||ios_base::out); fState(os); os.write(buffer,len); fState(os); os.close(); delete[] buffer; }
int _tmain(int argc, _TCHAR *argv[]) { PrepareForTestBinary(_T("D:\\!binary\\1\\11")); TestBinary(_T("D:\\!binary\\1\\11"),_T("D:\\!binary\\1\\22")); system("pause"); return 0; }
При этом такой способ никаких проблем не даёт (но и проблем моих с парсом не решает):
void TestBinary_bufferExch(tstring inPATH,tstring outPATH) { tifstream is; tofstream os; is.open (inPATH, ios_base::binary || ios_base::in ); os.open (outPATH,ios_base::binary ||ios_base::out); os << is.rdbuf(); is.close(); os.close(); }
Сопутствующие вопросы:
Как оптимально вырезать из потока все символы '0x00' ? Пока ничего умнее не придумал, как в цикле посимвольно сравнивать и все отличные от '0x00' писать в другой буфер(или поток). Как вообще правильно читать поток, содержимое и формат которого не известны? Прошу ткнуть в мало-мальски грамотный парсер(код пощупать).
Обновление
Пробовал даже так, никаких изменений.
void TestBinary(tstring inPATH,tstring outPATH) { LONGLONG len = 0; TCHAR * buffer = 0; tifstream is; fState(is); is.open (inPATH, ios_base::binary ||ios_base::in ); fState(is); is.seekg (0, ios::end); len = is.tellg(); is.seekg (0, ios::beg); buffer = new TCHAR [len]; memset(buffer,0,len); fState(is); is.read (buffer,len); fState(is); is.close(); tofstream os; fState(os); os.open (outPATH, ios_base::binary ||ios_base::out); fState(os); os.write(buffer,len); fState(os); os.close(); delete[] buffer; }
Обновление 2
Провёл доп. исследования. Проблема возникает только при наличии в файле 0x0D 0x0A (endl помещённый в поток). При наличии '\0' (0x00) проблема не возникает.


Ответ

В вашем коде мне кажется я вижу одну неточность. "Побитовое ИЛИ" должно писаться через один символ | (ios_base::binary |ios_base::in). В вашем случае это операция "логического ИЛИ" и результат его скорее всего равен 1 для обоих файлов.

Непонятная ошибка при печати из JasperReport

Печатаю в консольном приложении через JasperReport-6 несколько тысяч заданий в день на разные сетевые принтеры. Периодически вылетает ошибка:
Ошибка:No suitable print service found. net.sf.jasperreports.engine.export.JRPrintServiceExporter.exportReport(JRPrintServiceExporter.java:323)
При повторной отправке задания все отлично. Отловить отладчиком не могу. Этих ошибок в день около 100, а заданий несколько тысяч. Печатаю вот так:
jasperPrint = JasperFillManager.fillReport(getClass().getResourceAsStream(fn), parameters, cn); if (!jasperPrint.getPages().isEmpty()) { PrintRequestAttributeSet printRequestAttributeSet = new HashPrintRequestAttributeSet(); printRequestAttributeSet.add(new JobName("Picklist_ID" + picklistId + "", null)); if (ps != null) { System.out.println("PICKLIST_ID:" + picklistId + " WID:" + workshopId + " MS:" + ms + " " + curWorkMode.toString() + " PRINTER:" + ps.getName() + " " + new Date().toString() + " Prior" + priority); JRPrintServiceExporter exporter = new JRPrintServiceExporter(); exporter.setExporterInput(new SimpleExporterInput(jasperPrint)); SimplePrintServiceExporterConfiguration conf = new SimplePrintServiceExporterConfiguration(); conf.setPrintRequestAttributeSet(printRequestAttributeSet); conf.setPrintServiceAttributeSet(ps.getAttributes()); conf.setDisplayPageDialog(Boolean.FALSE); conf.setDisplayPrintDialog(Boolean.FALSE); exporter.setConfiguration(conf); exporter.exportReport(); }}
Ошибка вылетает на последней строчке:
exporter.exportReport();


Ответ

Я бы попробовал вручную добавить, может доп информация если что всплывет printServiceAttributeSet.add(new PrinterName("Epson Stylus 820 ESC/P 2", null)); printServiceAttributeSet.add(new PrinterName("hp LaserJet 1320 PCL 6", null)); printServiceAttributeSet.add(new PrinterName("PDFCreator", null));

Структура бд для ведения склада

Возникла задача организовать свою систему учета ведения склада/складов.
После некоторого обдумывания у меня получилась следующая схема бд:

где:
MeasureUnits - Справочник единиц измерения (кг/шт/прочее) DocumentTypes - Справочник типы документов (Приходная/Расходная накладная) Warehouses - Справочник складов (Список складов); MaterialAssets - Справочник подотчетных позиций ROFs - Таблица для задания наличия необходимого минимального/максимального количества на складе Documents - Таблица документов (Приход/Расход) ItemsDocument - Таблица список позиций для документа
Помогите придумать как хранить остатки по складу, т.е. какие поля следует включить в таблицу: Остатки
Был бы премного благодарен за советы касательно приведенной мной схемы: может что то стоит изменить.

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

Update2
в исходную схему внес следующие изменения:
ItemsDocument переименовал в DocumentItems в таблицу ROFs добавил поле MeasureUnitId, для того что бы было понятно в какой единице измерения отслеживать количество добавил таблицу Units - Справочник подразделений добавил макет таблицы Remains в которой будут остатки; добавил таблицу ConversionOfMeasureUnits, в данную таблицу планирую записывать коэффициент который будет использоваться для приведения из одной единицы измерения в другую.

Update3
для чего я сделал связь между DocumentItems и ConversionOfMeasureUnits
Предположим у нас на складе есть Проволока, в свое время она пришла в метрах и так и была оприходована, в один прекрасный момент эта проволока приходит в килограммах(поставщик сменился), в DocumentItems появляется запись следующего вида:
+----+------------+------------------+---------------+--------+ | Id | DocumentId | MaterialAssetsId | MeasureUnitId | Amount | |----+------------+------------------+---------------+--------| | 55 | 5 | 8 | 1 | 5 | +-------------------------------------------------------------+
где:
5 - идентификатор документа; 8 - идентификатор товарно-материальной ценности; 1 - ед. измерения в чем был оприходован данный товар; 5,000 - оприходованное количество
что бы перевести полученные килограммы и показывать остаток в нужных нам метрах кладовщик, через интерфейс программы добавляет запись в таблицу ConversionOfMeasureUnits следующего вида:
+----------------+-----------------+---------------------+ | DocumentItemId | AtMeasureUnitId | TransformationRatio | |----------------+-----------------+---------------------| | 55 | 2 | 0,100 | +--------------------------------------------------------+
где:
55 - идентификатор позиции в таблице DocumentItems 2 - индетификатор ед. измерения в которую будем переводить; 0,100 - в данном случае это вес одного метра проволоки
имея подобную структуру я смогу приводить одну ед. измерения в другую, и отображать(возможно и хранить) остаток в нужных единицах, и в тоже время приход/расход будет вестись в тех же единицах что и в бухгалтерии

Update4
На основании предложений и советов изменил схему следующим образом.

Вынес ед. измерения в справочник материалов; Коэффициент преобразования связал со справочником материалов, добавил два поля типа DateTime дата начала действия и дата окончания действия(default value = "31.12.9999 23:59:59.99") коэффициента;


Ответ

Единицы измерения надо ставить на конкретный материал (товар), а не на запись документа. Т.е. что бы конкретный товар везде был в одних единицах. А то вычисление тех самых остатков на складе будет весьма нетривиально. На склад по документу завели 3 тонны сахара, по другим документам со склада отгрузили 30 кг, 45000 г и 2 мешка. Вопрос: сколько кубических дециметров сахара осталось при относительной влажности 80% и температуре 70 градусов фаренгейта ?
А остатки - это сумма всех записей по данному товару из ItemsDocument, учетом отгрузок как отрицательных величин. Для удобства работы, и оптимизации по производительности можно либо фиксировать остаток на складе на конкретную дату или по точке ухода документов в архив. Или вести триггерами текущее значение. Структура во всех случаях простейшая:
MaterialAssetsId WarehouseId Ammount Date -- возможно, если нужна, дата последней операции или фиксации остатка
Правда что то мне подсказывает, что следующим шагом развития системы будет отслеживать товары в пределах склада с указанием стеллажей или как там место указывается. Тогда придется делать много записей остатков с указанием размещения, например
Upd: ConversionOfMeasureUnits очень странно привязана к записям в документах. С одной стороны я конечно подозреваю, что какие то сложные пересчеты могут быть к документу. С другой стороны, представить перевод грамм в килограмм по разным формулам на разных документах очень сложно. Я бы в таком случае в DocumentItems добавил бы поле "кол-во в базовой единице измерения", в таблицу товаров добавил "базовая единица". Коэффициенты пересчета (хорошо если формулы не понадобятся, не дай бог жидкие материалы, для которых приходится учитывать плотность) вынес отдельно. И еще конечно надо подумать, что будет если в одной поставке мешки по 30 кг, а в другой по 35. Но тут вы похоже все равно хотели, что бы человек к конкретному документу эти коэффициенты откуда то брал. Может произвести "Стандартный расчет" и позволить исправить уже посчитанное кол-во в базовой единице.
С другой стороны, если отгрузка идет всегда в той же единице и пол-мешка отсыпать не пытаются, то тогда вопрос а нужна ли некая базовая единица. Базовая нужна если потом хотят выдавать какие нибудь статистические формы например, что бы в них товар был без разбивки на единицы. Но готовы ли ради них обеспечить перевод и ввод корректных "базовых количеств".

Показатель ANR в Play Market'e

Что отображает показатель ANR в Play Market ?
Когда приложение падает с надписью "Приложение было остановлено" и пользователь нажал на кнопку отправить отчет или когда ?


Ответ

ANR - Application Not Responded - Приложение не отвечает. Зависло, в общем. Вроде как более 5 секунд выполняло некую задачу в основном потоке (UI) приложения.
И да, чтобы это в консоли появилось юзер должен нажать на "отправить отчёт", автоматически такие ошибки не отправляются. Для этого нужны спец. библиотеки.

POST запрос Retrofit 2.0

Возникла проблема при попытке создать POST запрос через retrofit по нажатию на кнопку.
public interface HZApi { @POST("/registration") public Call register(@Body ReqBody request); }
public class RespBody { String login; String password; boolean flag; }
public class ReqBody { String login; String password;
public ReqBody(String login, String password){ this.login = login; this.password = password; } }
public void ClickOK(View v){ Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://mysite.ru") .build(); HZApi api = retrofit.create(HZApi.class); ReqBody req = new ReqBody(login,password); Call call = api.register(req); call.enqueue(new Callback() { @Override public void onResponse(Call call, Response response) { Toast.makeText(getApplicationContext(),"OK",Toast.LENGTH_SHORT).show(); }
@Override public void onFailure(Call call, Throwable t) { Toast.makeText(getApplicationContext(),"!!!",Toast.LENGTH_SHORT).show(); } }) ; } }
На строке
HZApi api = retrofit.create(HZApi.class);
вылетает исключение java.lang.IllegalStateException: Could not execute method for android:onClick.
Не могли бы вы подсказать, с чем это может быть связано?


Ответ

В onCreate() \ onCreateView()
Проверьте инициализацию вашей кнопки
findViewById(R.id.my_button).setOnClickListener(this);
В onClick
@Override public void onClick(View v) { switch (v.getId()) { case R.id.my_button: //ваш запрос break; } }

Подстроить текст под ширину блока

У меня есть поп-ап и у него прописана ширина. Я добавляю два div

Phone Number: 02077 159241
We have a chiller
We have a freezerWe have a freezerWe have a freezerWe have a freezerWe have a freezerWe have a freezerWe have a freezerWe have a freezerWe have a freezerWe have a freezerWe have a freezerWe have a freezer


и когда в div`е storeRangeChillerFreezer в span добавляю много текста, появляется полоса прокрутки.
Как сделать так, чтобы прокрутка не появлялась, а текст автоматически переводился на новую строку?
Спасибо


Ответ

Исправила это, когда убрала white-space: nowrap. Все заработало.

ActiveAdmin, Несколько селектов в форме для одного поля таблицы

Как сделать следующее( возможно ли вообще?): Имеем в таблице бд одно поле типа строка, в форме activeadmin для этого поля несколько селектов, к примеру один со списком цифр, второй букв, а записываться соответственно должно значение вида "1ф".


Ответ

Пример для модели User и поля full_name и виртуальных полей first_name и last_name из которых должно получиться поле full_name
Для начала обманем Formtastic, который все поля берет с модели, иметь нужные поля. Как я понял из условия, "виртуальные" поля там не должны храниться:
class User < ActiveRecord::Base
attr_accessor :first_name, :last_name
# ...
end
В описании темплейта Active Admin перегрузим методы контроллера create и update
ActiveAdmin.register User do permit_params :first_name, :last_name
# index
# filters
form do |f| f.inputs do f.input :first_name, as: :select, collection: ["Ivan", "Petr"] f.input :last_name, as: :select, collection: ["Ivanov", "Petrov"] end end
controller do def set_full_name first_name, last_name @user.full_name = "#{first_name} #{last_name}" @user.save end
def create create! do redirect_to(admin_users_path) and return if set_full_name(params[:user][:first_name], params[:user][:last_name]) end end
def update update! do redirect_to(admin_users_path) and return if set_full_name(params[:user][:first_name], params[:user][:last_name]) end end end end
Пример привел в образовательных целях, в реальном проекте такое лучше не использовать, хотя бы потому, что "виртуальные" поля first_name и last_name будут всегда обнуляться при каждом построении формы.
Если вы захотите их назначать автоматически и напишете что-то такое:
class User < ActiveRecord::Base
attr_accessor :first_name, :last_name
def first_name full_name.split(' ').first end
def last_name full_name.split(' ').last end end
То при введении имени из трех слов вы будете парсить неверно. И, конечно же, совсем не сможете правильно распарсить ваш пример с символами и буквами, которые вообще никак не разделяются.
Если подразумевается, что поле full_name не будет показываться на сайте, то можно ввести некоторый разделитель в функции конкатенации:
def set_full_name first_name, last_name @user.full_name = "#{first_name};#{last_name}" @user.save end
Возможна еще куча других нюансов, что говорит нам о том, что мы не должны так делать, а лучше бы завести отдельные поля в БД first_name и last_name
И еще вариант, если по условию вы можете конкатенировать не только при редактировании в панели администратора, то вместо перегрузки контроллера, можно повесить callback на событие before_save
before :save do full_name = "#{first_name} #{last_name}" end
Внимание! Использование callback-ов не есть хороший стиль программирования. Он может накладывать сложности при тестировании ActiveRecord моделей, когда у вас на элементарные действия будет выполняться очень много кода. Используйте очень осторожно.

Как анимировать динамически создаваемые контролы XAML

У меня есть список, с привязкой к данным. В этом списке есть элемент, который требуется анимировать. Допустим гиппотечиская страничка может выглядеть так:




В данном примере по Тапу на элементе списка должен появляться скрытый черный квадратик. Однако на практике приложение падает с ошибкой
System.Exception: No installed components were detected. Cannot resolve TargetName Control. at Windows.UI.Xaml.Media.Animation.Storyboard.Begin() at Microsoft.Xaml.Interactions.Media.ControlStoryboardAction.Execute(Object sender, Object parameter) at Microsoft.Xaml.Interactivity.Interaction.ExecuteActions(Object sender, ActionCollection actions, Object parameter) at Microsoft.Xaml.Interactions.Core.EventTriggerBehavior.OnEvent(Object sender, Object eventArgs)
Может можно как-то по-другому сделать?


Ответ

У меня сработало так (пробовал только на UWP под Windows 10):


Проблема в том, что имя Control, на которое ссылается ваша анимация через Storyboard.TargetName, должно быть видимо на этапе компиляции. Когда анимация и DataTemplate описаны вместе, они видят друг друга.

Обновление: если вам нужно проигрывать разные анимации, можно использовать переключение в code-behind. Например, так:
False True False

и в code-behind:
void Grid_Tapped(object sender, TappedRoutedEventArgs e) { var grid = (Grid)sender; grid.Tag = !(bool)grid.Tag; }

Ну и если вам не нужна реальная анимация, а только включить/выключить видимость элемента, можно ещё проще:

и в code-behind
void Grid_Tapped(object sender, TappedRoutedEventArgs e) { var grid = (Grid)sender; var control = (StackPanel)grid.FindName("Control"); control.Visibility = control.Visibility == Visibility.Collapsed ? Visibility.Visible : Visibility.Collapsed; }

Ну и ещё один вариант, без code-behind, но с одним конвертером. Идея в том, что мы по событию tapped меняем значение Tag между true и false, а к этому значению через DataTrigger прикрепляем анимацию.
False True False

Вам понадобится всего лишь простой конвертер:
class BooleanNegatingConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, string lang) { return !(bool)value; }
public object ConvertBack(object value, Type targetType, object parameter, string lang) { return !(bool)value; } }

Как в Django CMS отображать разные страницы для разных городов?

В Django CMS есть удобная сегментация по языкам, позволяющая забить в админке одну страницу разными данными для разных языков.
Есть задача выводить разные данные на странице для разных городов. Хотелось бы что-то похожее на сегментацию по языкам. Но как не искал, ничего подобного не нашёл.
Единственное, что пришло пока в голову: поднять GeoIP на Nginx, настроить редирект на субдомены вида .domain.com и эксплуатировать django sites framework. Но это не настолько изящный вариант, насколько хотелось бы.


Ответ

Невозможно сделать так, как мне хотелось. Да и других готовых решений для геосегментирования контента я не нашёл. Пришлось написать свой плагин - djangocms-geoplaceholder. Возможно, он пригодится кому-нибудь ещё.

Можно ли определить набор необходимых библиотек для ехе без его загрузки? [дубликат]

На данный вопрос уже ответили: Анализ сборок дотнета 1 ответ Есть несколько различных .net запускаемых файлов. Можно ли, не загружая их, узнать, какие библиотеки будут загружены при его работе? Точнее, какие References имел его проект, если смотреть как будто бы из VisualStudio?


Ответ

Можно. Используйте ILDasm, Reflector, dotPeek. Открываете в них exe файл и в разделе References смотрите, на какие сборки он ссылается (скриншот из dotPeek):


Программно получить список зареференсенных сборок можно так:
var assembly = Assembly.LoadFile("MyApp.exe"); foreach (var reference in assembly.GetReferencedAssemblies()) { Console.WriteLine(reference.FullName); }
Для более глубокого анализа удобнее использовать библиотеку Mono.Cecil
var assembly = AssemblyDefinition.ReadAssembly(assemblyFilePath); foreach (var reference in assembly.MainModule.AssemblyReferences) { Console.WriteLine(reference.FullName); }

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

В этой статье автор пытается рассказать о том, чем являются имена массивов в Си. Он показывает, что a и &a имеют одно и то же числовое значение, то разные типы. Имя a является указателем на первый элемент массива и имеет тип int *, а &a - то же самое, что &a[0], и является указателем на массив из трех чисел.
Пример в конце статьи:
preserve do :escaped (gdb) print a + 1 $10 = (int *) 0x7fff5fbff570 (gdb) print &a + 1 $11 = (int (*)[3]) 0x7fff5fbff578
И цитата автора: Note that adding 1 to a adds four to a’s address, whereas adding 1 to &a adds twelve!
Почему здесь написано, что к &a прибавляется 12, когда по логу видно, что прибавляется 8? Почему прибавление единицы к &a инкрементирует значение гораздо больше, чем прибавление единицы к a? Что это за игра с типами такая?


Ответ

По поводу первого вопроса
Почему здесь написано, что к &a прибавляется 12, когда по логу видно, что прибавляется 8?
Стоит обратить внимание, что в логе отображены результаты сложения, и между ними разница действительно 8 и это вводит в заблуждение. Но, чтобы узнать сколько прибавилось, нужно смотреть на начальный адрес
= preserve do :escaped (gdb) x/4xb a 0x7fff5fbff56c: 0x01 0x00 0x00 0x00 (gdb) x/4xb &a 0x7fff5fbff56c: 0x01 0x00 0x00 0x00
И если смотреть разницу относительно него, то можно увидеть, что в первом случае она равно 4, а во втором - 12 как и написано в статье.
Что касается второго вопроса
Почему прибавление единицы к &a инкрементирует значение гораздо больше, чем прибавление единицы к a? Что это за игра с типами такая?
то возможно поможет перевод аналогичного вопроса на английском
Имя массива обычно вычисляется как адрес первого элемента, так что array и &array имеют одинаковое значение (но разные типы, array+1 и &array+1 не будут равны, если длина массива больше одного элемента).
Есть два исключения из этого правила: когда имя массива является операндом sizeof или унарного & (address-of) имя указывает на сам массив, поэтому sizeof возвращает размер всего массива, а не размер указателя.
Для массива определенного как T array[size], array будет иметь тип T *. При инкрементировании его вы получите следующий элемент в массиве.
&array возвращает тот же адрес, но при этом тип указателя будет уже T(*)[size] - т.е. это указатель на весь массив, а не отдельный элемента. И когда вы увеличиваете этот указатель он добавляет размер всего массива, а не размер отдельного элемента.

RecyclerView количество строк

Можно ли указать количество строк в RecyclerView, когда в горизонтальном режиме прокрутки, к примеру в GridLayout указывается android:columnCount="4"? существует ли что-то такое для RecyclerView?


Ответ

решил проблему с использованием GridLayoutManager
rv=(RecyclerView)findViewById(R.id.rv); GridLayoutManager glm = new GridLayoutManager(this, 4); rv.setLayoutManager(glm); rv.setHasFixedSize(true);

error: 'Access denied for user 'root'@'localhost' (using password: NO)' MAMP

Скачал MAMP, вбиваю в терминале:
./mysqladmin -u root - password "newpassword"
и выдает это ошибку error:
'Access denied for user 'root'@'localhost' (using password: NO)'
Что делать?


Ответ

Утилиты MySQL позволяют задать пароль аккаунта при помощи параметра --password или его краткой формы -p. В полной форме, если вы не указываете пароль, он запрашивается у вас отдельно
./mysqladmin -u root --password
Вы можете указать пароль в командной строке, через =
./mysqladmin -u root --password=newpassword
В краткой форме параметра -p, без указания пароля, пароль будет запрошен сразу после выполнения команды
./mysqladmin -u root -p
Или вы можете указать его сразу после параметра введя его без пробела и дополнительных символов
./mysqladmin -u root -pnewpassword
Однако, указывать пароль в командной строке считается дурным тоном, так как команда остается в логах, которые в случае взлома могут быть использованы злоумышленником для увеличения привилегий. Если использование пароля в команде необходимо, можно предварить команду пробелом
$ ./mysqladmin -u root -pnewpassword
В этом случае она не попадет в историю. Однако, на практике чаще прибегают локальному конфигурационному файлу пользователя ~/.my.cnf, в котором указывают предпочтительный логин и пароль, выставляя права доступа на него таким образом, чтобы прочитать его мог только владелец.
[client] user=root password=newpassword

Как обработать POST запрос через admin django

Есть две модели:
class Question(models.Model): question_text = models.CharField(max_length=200) count_choice= models.IntegerField(default=0) pub_date = models.DateTimeField('date published') def __str__(self): return self.question_text
class Choice(models.Model): question = models.ForeignKey(Question, on_delete=models.CASCADE) choice_text = models.CharField(max_length=200) votes = models.IntegerField(default=0) def __str__(self): return self.choice_text
Вид из admin django
Мне необходимо, что бы при создании в колонку count_choice модели question записывалось кол-во choice, как это сделать?


Ответ

В admin.py
class QuestionAdmin(admin.ModelAdmin): def save_formset(self, request, form, formset, change): super(QuestionAdmin, self).save_formset(request, form, formset, change) obj = form.save(commit=False) choices_count = Choice.objects.filter(question=obj).count() obj.count_choice=choices_count obj.save()
Обратите внимание, что в этом варианте переопределяется метод QuestionAdmin, а не ChoiceAdmin. И срабатывает он при любых операциях, не только создании. Можно добавить проверку аргумента change, но тогда count_choice будет иметь неверное значение при удалении вариантов.

Как изменить позицию ScrollView при запуске фрагмента программно?

В onCreateView добавил следующий код и ничего не работает, а если создаю кнопку myButton и добавляю ему слушателя при нажатии вставив тот же самый код то все работает, как сделать так чтоб все работало не нажимая на кнопку автоматически при создании
myScroll = (ScrollView) view.findViewById(R.id.myScroll); myScroll.scrollTo(0, 0);


Ответ

А если так
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { @Override public void run() { //Тут код выполнится чрез 0.5с myScroll.scrollTo(0,0); } }, 500);
?

Карта браузерной стратегии

Создаю карту для браузерной игры (стратегии). Карта состоит из клеток (tile) ... На данный момент карта обновляется при нажатии на стрелочки рядом с картой, сама карта генерируется с помощью цикла PHP (вся информация о деревнях и ресурсах на карте - храниться и выбирается из БД) ...
Я понимаю что генерировать карту каждый раз при обновлении координат (при передвижении по карте) , это очень тяжелый процесс как для сервера так и для клиента...
То что сейчас:
Принял решение изменить карту:
Использовать AJAX (для динамического обновления карты) Использовать JSON Для получения информации о городах на карте с помощью API Использовать Скрол по X и Y для прокрутки карты по осям ( такую систему использовали и используют Travian )
Первые 2 пункта - не вызывают вопросов вообще ... Вот насчет 3, это проблема. Сначала выбор пал на плагин Jquery Eco-Scroll.js ... Но не смог найти как прикрутить "начальные координаты" , чтобы не 0:0 грузил, а допустим 20:5 ... Прощу помочь найти решения для реализации карты (и да я понимаю, что карта перекачует из изометрии в 2D ). Самый большой плюс Eco-Scroll.js это предзагрузка клеток .


Ответ

Самым простым способом оказалось использовать JS (Jquery). Написав небольшую библиотеку , которая генерирует слой клеток размером 20х20 (400 клеток), дальше скрипт грузит данные с сервера используя AJAX и получает ответ в JSON (создается псевдо реал тайм). После того как скрипт уже попал в кэш , загрузка и работа карты - становиться просто великолепной, небольшой скрин:
Довольно интересным решением стало использование draggable , из пакета JQuery. Именно он позволил сделать перетаскивание карты (свайп если вам угодно) , используя математические вычисления удалось научить скрипт понимать стороны света , и перемещать в зависимости от смещения карты относительно страницы :)

Приложение падает на SetcontentView(Мое активити), в котором используются наследники от Button

Создала свой класс SapperButton extends Button, во вьюхе накидала таких кнопок этого вида. При просмотре дезайнера выдается окно с
The following class could not be found - SapperButton
А после запуска при переходе на соответствующий лейоут с этой вьюхой все падает. Понимаю, что не может найти мой класс-наследник от Button. Но почему и как это исправить?
Вот начало активити, из которого вызывается вьюха:
package com.example.helen.mygamesapper;
import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.TextView;
public class GameActivity extends Activity implements View.OnClickListener {
int numBombs; Button[][] fields;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_game); TextView numBombText = (TextView) findViewById(R.id.numBombText);
Intent intent = getIntent(); numBombs = intent.getIntExtra("numBombs", 10);
Вот мой класс-наследник от кнопки:
package com.example.helen.mygamesapper;
import android.content.Context; import android.util.AttributeSet; import android.widget.Button; public class SapperButton extends Button {
private boolean isOpen = false; private boolean isBomb = false; private boolean isBlown = false; /* public SapperButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); } */ public SapperButton(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); }
public SapperButton(Context context, AttributeSet attrs) { super(context, attrs); }
public SapperButton(Context context) { super(context); }

public boolean isOpen() { return isOpen; }
public void setOpen(boolean open) { isOpen = open; } public void setBomb(boolean bomb) { isBomb = bomb; }
public boolean getIsBomb() { return isBomb; }
public boolean isBlown() { return isBlown; }
public void setBlowned(boolean isBlowning) { isBlown = isBlowning; }
}
Сама вьюха:




android:paddingTop="5pt" android:paddingBottom="5pt" android:weightSum="1.0">




Лог ошибки:
03-26 16:24:52.044 9706-9706/com.example.helen.mygamesapper E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.helen.mygamesapper, PID: 9706 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.helen.mygamesapper/com.example.helen.mygamesapper.GameActivity}: android.view.InflateException: Binary XML file line #44: Error inflating class SapperButton at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2358) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2410) at android.app.ActivityThread.access$800(ActivityThread.java:155) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1331) at android.os.Handler.dispatchMessage(Handler.java:110) at android.os.Looper.loop(Looper.java:193) at android.app.ActivityThread.main(ActivityThread.java:5395) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:837) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:653) at dalvik.system.NativeStart.main(Native Method) Caused by: android.view.InflateException: Binary XML file line #44: Error inflating class SapperButton at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:707) at android.view.LayoutInflater.rInflate(LayoutInflater.java:755) at android.view.LayoutInflater.rInflate(LayoutInflater.java:758) at android.view.LayoutInflater.inflate(LayoutInflater.java:492) at android.view.LayoutInflater.inflate(LayoutInflater.java:397) at android.view.LayoutInflater.inflate(LayoutInflater.java:353) at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:312) at android.app.Activity.setContentView(Activity.java:1952) at com.example.helen.mygamesapper.GameActivity.onCreate(GameActivity.java:20) at android.app.Activity.performCreate(Activity.java:5277) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1088) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2322) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2410)  at android.app.ActivityThread.access$800(ActivityThread.java:155)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1331)  at android.os.Handler.dispatchMessage(Handler.java:110)  at android.os.Looper.loop(Looper.java:193)  at android.app.ActivityThread.main(ActivityThread.java:5395)  at java.lang.reflect.Method.invokeNative(Native Method)  at java.lang.reflect.Method.invoke(Method.java:515)  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:837)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:653)  at dalvik.system.NativeStart.main(Native Method)  Caused by: java.lang.ClassNotFoundException: Didn't find class "android.view.SapperButton" on path: DexPathList[[zip file "/data/app/com.example.helen.mygamesapper-1.apk"],nativeLibraryDirectories=[/data/app-lib/com.example.helen.mygamesapper-1, /vendor/lib, /system/lib]] at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56) at java.lang.ClassLoader.loadClass(ClassLoader.java:497) at java.lang.ClassLoader.loadClass(ClassLoader.java:457) at android.view.LayoutInflater.createView(LayoutInflater.java:559) at android.view.LayoutInflater.onCreateView(LayoutInflater.java:652) at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:66) at android.view.LayoutInflater.onCreateView(LayoutInflater.java:669) at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:694) at android.view.LayoutInflater.rInflate(LayoutInflater.java:755)  at android.view.LayoutInflater.rInflate(LayoutInflater.java:758)  at android.view.LayoutInflater.inflate(LayoutInflater.java:492)  at android.view.LayoutInflater.inflate(LayoutInflater.java:397)  at android.view.LayoutInflater.inflate(LayoutInflater.java:353)  at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:312)  at android.app.Activity.setContentView(Activity.java:1952)  at com.example.helen.mygamesapper.GameActivity.onCreate(GameActivity.java:20)  at android.app.Activity.performCreate(Activity.java:5277)  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1088)  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2322)  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2410)  at android.app.ActivityThread.access$800(ActivityThread.java:155)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1331)  at android.os.Handler.dispatchMessage(Handler.java:110)  at android.os.Looper.loop(Looper.java:193)  at android.app.ActivityThread.main(ActivityThread.java:5395)  at java.lang.reflect.Method.invokeNative(Native Method)  at java.lang.reflect.Method.invoke(Method.java:515)  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:837)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:653)  at dalvik.system.NativeStart.main(Native Method)
 


Ответ

Для кастомных View в разметке xml нужно указывать полный путь до класса:

Преимущества WebApi перед Asp.net mvc при реализации api

Добрый день! Возник следующий вопрос. Имеется asp.net mvc приложение, работающее с некой бд (sql server). И есть еще одно приложение, для которого нужно дать некий api для работы с первым приложением (по большому счету с его базой данных). Предполагается что api должно представлять собой набор http методов, позволяющих получать ответ в формате json. Напрашивается использование технологии ASP.NET Web Api, про которую я слышал ранее. Проблема вот в чем. Я почти ничего не знаю об этой технологии (ну только что она позволяет достаточно легко и удобно создавать такие api и более "легкая" по сравнению с wcf). Пока что я вижу более простую для себя альтернативу в виде создания дополнительного контроллера в своем asp.net mvc приложении с экшнами, возвращающими JsonResult. Ну в общем такая простенькая реализация api. Преимущество такого подхода для меня состоит в том, что в этом случае не придется создавать новый проект и разворачивать его отдельно (мелочь но все же) а также что в mvc приложении доступ к данным происходит через orm и в случае с web api придется как-то дублировать код этого доступа и в web api проекте.
Теперь сам вопрос: есть ли какие-то весомые преимущества у технологии web api для решения данной задачи? Или наоборот есть ли какие-то существенные недостатки для решения этой задачи у подхода с отдельным контроллером и экшнами возвращающими JsonResult? Просто меня гложет сомнение что раз существует такая технология как WebApi,то наверное реализовывать свой api с помощью такого кустарного метода как простые Json-экшены несколько глупо? Наставьте пожалуйста на путь истинный! заранее спасибо!


Ответ

WEB API крайне удобен для создания RESTful-сервисов, который Вам как раз и нужно будет создать. Есть у него и свои нюансы, если MVC сочетает в себе и контроллеры и движок представления, то Web Api - это только контроллеры, возвращающие данные (JSON, XML или др. - не важно), которые работают с HTTP. Вы не сможете, к примеру, выполнить переадресацию пользователя на другую страницу, но вы можете послать HTTP-код, соответствующий редиректу. Вы не сможете отобразить ошибку авторизации, но вы пошлёте на клиент статус-код, в котором покажете ошибку 401 и сообщение к нему.
Абсолютно без разницы как и на чём вы будете писать клиентское приложение - ведь WebApi - это HTTP-стандарт.
Но если не брать в расчёт такие понятия как вид выводимых данных - то то, что происходит в контроллере - практически ничем не отличается от обычного MVC! Так что не стоит переживать о том, что не сможете использовать ORM

Помогите пожалуйста с запросом SQL (Oracle). Having, Group by, агрегатная функция от агрегатной функции

Задание - вывести фамилию-имя начальника отдела и название отдела, в котором сотрудники выполнили максимальное количество проектов. У меня получился такой запрос, но выводит он не совсем то, что нужно. Сделал его по примеру отсюда (второй пункт).

SELECT department_name, max_amount FROM ( SELECT dep_name AS department_name, COUNT(rel_prj_id) AS projects_amount FROM employees INNER JOIN departments ON emp_dep_id = dep_id INNER JOIN rel_prj_emp ON rel_emp_id = emp_id GROUP BY dep_name ) X INNER JOIN ( SELECT MAX(projects_amount) AS max_amount FROM ( SELECT dep_name AS department_name, COUNT(rel_prj_id) AS projects_amount FROM employees INNER JOIN departments ON emp_dep_id = dep_id INNER JOIN rel_prj_emp ON rel_emp_id = emp_id GROUP BY dep_name ) X ) Y ON projects_amount = max_amount
Вывод, при том, что проекта всего три:
В чем проблема - я думаю, вы поймёте, если посмотрете на схему БД. Каждому отделу должно соответствовать несколько проектов, но отделы и проекты связаны через таблицу сотрудников - и поэтому в моём запросе каждому отделу соответствует больше записей, чем нужно. Группирую по названию отдела, а получается, что в каждой группе - сотрудники этого отдела. Как связать таблицы иначе или сгруппировать иначе - я не придумал, в ступоре нахожусь. Если зайти с другой стороны, сгруппировать по id проекта - в каждой группе будет количество сотрудников, которое работало над проектом, тоже не то. Нужно решение задачи именно по этой схеме. Я знаю, что можно упростить, но задание учебное. Скрипт создания БД: http://pastebin.com/hnHnENpX

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


Ответ

SELECT emp_first_name,emp_last_name,department_name, max_amount FROM ( SELECT dep_name AS department_name,e2.emp_first_name,e2.emp_last_name, COUNT(distinct rel_prj_id) AS projects_amount FROM employees e1 INNER JOIN departments ON e1.emp_dep_id = dep_id INNER JOIN rel_prj_emp ON rel_emp_id = e1.emp_id INNER JOIN employees e2 ON e2.emp_id=dep_manager_id GROUP BY dep_name,e2.emp_first_name,e2.emp_last_name ) X INNER JOIN ( SELECT MAX(projects_amount) AS max_amount FROM ( SELECT dep_name AS department_name, COUNT(distinct rel_prj_id) AS projects_amount FROM employees INNER JOIN departments ON emp_dep_id = dep_id INNER JOIN rel_prj_emp ON rel_emp_id = emp_id GROUP BY dep_name ) X ) Y ON projects_amount = max_amount
Хотя верхний подзапрос немного странно смотрится, логичнее бы выглядело, если бы отделы были первой таблицей и к ней все клеилось. Хотя в данном случае порядок ни на что не влияет (т.к. в inner join таблицы слева и справа равнозначны).

Что происходит в websocketHandler'е в данном случае?

Работая с vert.x core 3.2.1 увидел такую конфигурацию сервера, использующего веб-соккет:
vertx.createHttpServer().websocketHandler(ws -> ws.handler(ws::writeBinaryMessage)).requestHandler(req -> { if (req.uri().equals("/")) req.response().sendFile("ws.html"); }).listen(8080);
По записи я понял,что на платформе вертекса мы создаем http-сервер который с помощью метода listen,слушающего порт 8080 находится в ожидании возможного к нему подключения. Также тут используется вебсокетный хендлер, который связан с request-хендлером. Но четкого понимания о том,что происходит в websocketHandler нет. Лямбда-выражения и ::-оператор меня запутали. Объясните пожалуйста что исполняет данный код, или если возможно,распишите эту конструкцию без лямбд.


Ответ

После проб и ошибок,вроде бы удалось привести это заклинание с лямбдами к более простому и громоздкому виду:
server.websocketHandler(ws -> ws.handler(ws::writeBinaryMessage)) .requestHandler(req -> { if (req.uri().equals("smile")) req.response().end("hello");});
server.websocketHandler(new Handler() { @Override public void handle(ServerWebSocket webs) { webs.writeBinaryMessage(Buffer.buffer()); } }).requestHandler(new Handler() { @Override public void handle(HttpServerRequest req) { if (req.uri().equals("smile")) req.response().end("hello"); } });
В итоге видим следующее:первый хендлер в данном туториале работает с веб-сокетным соединением и в нем можно осуществлять обмен сообщениями, второй хендлер предназначен для работы с http и выводит в браузер "hello". Таким образом вертекс предоставляет набор интерфейсов(хендлеров),которые позволяют работать с соединениями различного типа.

Получить доступ к wall.post в vk

У меня есть сайт с которого я хотел бы постить статьи в мою группу в Вконтакте. Подключение происходит нормально, выскакивает окно с подтверждениями прав, но при отправки запроса содержащего метод wall.post выдает ошибку 15(доступ к методу закрыт). Вот так выглядит запрос при авторизации
Авторизация Вконтакте
код wall.post:
$sRequest = "https://api.vkontakte.ru/method/wall.post?owner_id=$vkontakteGroupId=&from_grou‌​p=1&access_token=$vkontakteAccessToken&message=$text";
в нем кроме сообщения я ничего не пробовал передать


Ответ

Недавно совсем писал модуль для постинга в группы, поэтому отвечу. Вам необходимо создать новое приложение Standalone типа. У приложения такого типа, к сожалению, нельзя указать домен (и автоматизировать тем самым получение временных токенов доступа). Поэтому получать "вечный" токен нужно вручную.
В остальном всё как у вас:
https://api.vk.com/oauth/authorize?client_id=&scope=offline,wall,groups&redirect_uri=https://vk.com&response_type=code
Копируете code из адресной строки, и делаете запрос на получение токена:
https://oauth.vk.com/access_token?client_id=&client_secret=&redirect_uri=https://vk.com&code=
К счастью, в этом случае токен не привязан к IP адресу (в отличие от стандартной OAuth авторизации), поэтому возможно сделать эти операции через браузер, а токен прописать в своё приложение (например, в PHP скрипт, который работает с другого IP).

Django REST Framework - как заполнить шаблон данными без использования Django моделей?

Как заполнить шаблон без моделей? Использую Django REST, python 3.4, Angular JS
Предположим, есть 4 страницы в виде шаблонов: main.html, page1.html, page2.html, page3.html
На странице main отображается список, который получается из запроса к базе данных. При выборе какого-либо пункта необходимо осуществлять переход на страницу page1, и на ней отображать список, полученный также из результатов выполнения запроса к базе данных (база данных не Django), но уже с учетом выбранного на странице main пункта, т.е. передать несколько параметров в REST, заполнить шаблон page1.html результатами выполнения запроса и отобразить итоговую страницу. Далее при выборе пункта осуществлять аналогично переход на страницу page2, с нее на page3 и т.д.
Просто делать у пунктов ссылки вида /page1/type=sometype&id=1 на странице main, на page1 - /page2/type=secondtype&id=6 и т.д? Какого типа лучше использовать класс для обработки запросов - APIView? Пытаюсь использовать APIView, перехожу по ссылке вида /page1?id=1 Вот пример без type параметра, только с id
class SomeAPI(APIView): permission_classes = [permissions.AllowAny]
def get(self, request, *args, **kwargs): if (request.GET.get('id',None)): ... # result = получаю из базы данных набор записей на основе id return Response({'res':result}, template_name="page1.html")
в urls.py: url(r'^page1'), SomeAPI.as_view()
В шаблоне page1.html
... {{item}} ...
Записи возвращаются верно (т.е. с получением данных из БД проблем нет), но отображаются не в шаблоне page1.html, а на странице стандартного шаблона REST API в виде JSON-структуры
{ "res": [ { "item": "1" }, { "item": "2" }, { "item": "3" }, { "item": "4" } ] }
По сути мне нужно объединить функционал TemplateView + APIView. Можно было бы аналогично, как на странице main, из контроллера AngularJS запрашивать у APIView JSON результат методом GET, и заполнять template. Но для page1, page2, page3 нужно использовать id. Передать запросом GET его не проблема, и сформировать ответ в APIView тоже, но как передать в контроллер для страницы page1 этот id со страницы main, например? И как заполнить на основе JSON-ответа шаблон?


Ответ

Чтобы отправить словарь в шаблон, нужно использовать TemplateHTMLRenderer в параметре renderer_classes,а сам шаблон добавляется в параметр template_name
from rest_framework.renderers import TemplateHTMLRenderer from rest_framework.response import Response from rest_framework.views import APIView
class SomeAPI(APIView): renderer_classes = [TemplateHTMLRenderer] template_name = 'page1.html'
def get(self, request, *args, **kwargs): ... return Response({'res':result})
Документация по работе с шаблонами
Вообще лучше разделить бекенд и фронтенд, роутинг настроить в Angular, а REST использовать только для отправки данных.

как сделать градиент c краёв к середине?

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


Но таким образом у меня градиент идет сверху вниз
вот так

А мне нужно сделать так, чтоб градиент шел от левой и правой стороны к центру
вот так

Подскажите как это можно сделать?


Ответ

Вроде как-то так, используя android:centerColor


Конструкция try/catch. Проблемы с FileInputStream

Требуется считать xls файл. Но try никогда не выполняется, а выполняется условие из catch. В итоге bb={“0,0,0,0”}. Не могу понять, что я делаю не так. Файл лежит в папке проекта.
Перемещение файла в другое место, изменение имени ничего не дало. Думала, что дело в том, что это xls, но даже с txt тоже самое.
Book bb = new Book(); String[] mas = bb.boob();
public class Book { public String[] data = new String[4];
public String[] boob() { try(FileInputStream fis = new FileInputStream("list.xls")) { //Workbook wb = new HSSFWorkbook(fis); for(int i=0; i<4; i++){ data[i] = "1"; } fis.close(); return data; } catch (IOException e){ String[] d ={"0","0","0","0"}; return d;} } }


Ответ

Надо было файл открывать используя assets. Например, fis = getAssets().open("list.xls");

Копирование части окна в буфер

Есть форма WPF. У формы в качестве украшалки вокруг окна тень. Тень прописана своя используя DropShadowEffect. WindowsStyle и прочее установлено в none, соответвенно, так как она является частью окна, то про нажатии Alt+PrintScreen окно копируется вместе с тенью, и соответвенно с тем, что под ней. Как можно реализовать перехват нажатия данной комбинации и копировать в буфер определенный участок окна? Например с отступом со всех сторон по 15 пикселей? UPD: в данном случае предположу что можно не блокировать комбинацию Alt+PrintScreen а получить скриншот окна в обычном событии Нажатия клавиш в фокусе окна, и об аботая его поместить в буфер урезанную версию.


Ответ

Подписка на сочетание клавиш, полагаю, делается так же, как и всегда — с помощью функции RegisterHotKey (правда не гарантирую, что система позволит перекрыть системное сочетание клавиш). В .NET встроенной обёртки нет.
Создание скриншота — традиционный GetDC(0). В .NET обёрнуто в Graphics.CopyFromScreen
За тень окон отвечает система, поэтому вам придётся брать скриншот части экрана, которое занимает окно, плюс запас под тень. Кажется, размеры тени прошиты где-то в поторохах Aero, поэтому размер придётся угадывать на глаз. Так как WPF использует всякие умные масштабирования, то на габариты окна полагаться нельзя, поэтому советую брать габариты напрямую из WinAPI, иначе при масштабе, отличном от 100%, всё сползёт.
Правда, учитывая, сколько это мороки, я бы для начала задался вопросом: а настолько ли оно надо? Гораздо проще положить под окно белый фон, сделать скриншот всего экрана, а потом вырезать нужное. Плюс есть зоопарк программ, которые сделают это удобно и приятно.

TimePicker не сохраняет значение

В своем приложении я использую TimePicker. Обнаружила, что если, выбирая время, не использовать кнопки "+", "-", а сразу набрать нужное количество часов или минут, то оно почти никогда не сохраняется. Например, если в часах я наберу 8, то это значение не сохранится. Если наберу 08, то сохранится. Если использую "+", "-", то все в порядке. Меня такая ситуация не устраивает. Может быть, кто-то подскажет как это исправить. Слушатель:
picker.setOnTimeChangedListener(new TimePicker.OnTimeChangedListener() { @Override public void onTimeChanged(TimePicker view, int hourOfDay, int minute) { Log.d("%%%%%%%%%%%%%", "new time: " + hourOfDay + ":" + minute); } });
не выводит сообщения, если я не использую кнопки "+", "-", и выводит, если использую.


Ответ

Помогла команда timePicker.clearFocus() перед считыванием данных из timepicker. Ответ был здесь