Страницы

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

среда, 14 ноября 2018 г.

Реализация равновесия(аналог весов с песком )

И так у нас есть терезы , к ним мы будем вешать блоки ( реализовал через draggable) !Как сделать так чтоб , когда вешаем на терезы блок они опускались в низ, когда добавляли вес с другой стороны , тогда они приводились в равновесия!
$(".state").draggable(); $('.obj_block1').draggable(); $(".top").draggable(); .state { background-image: url(../img/Object1.png); background-repeat: no-repeat; height: 401px; width: 300px; cursor: pointer; } .top { background-image: url(93bus.png); background-repeat: no-repeat; height: 40px; width: 400px; cursor: pointer; } .obj_block1 { background-image: url(../img/block1.png); background-repeat: no-repeat; height: 70px; width: 70px; cursor: pointer; }



Ответ

$.fn.animateRotate = function(angleFrom, angleTo, duration, easing, complete) { var args = $.speed(duration, easing, complete); return this.each(function(i, e) { args.complete = $.proxy(args.complete, e); args.step = function(now) { $.style(e, 'transform', 'rotate(' + now + 'deg)'); }; $({ deg: angleFrom }).animate({ deg: angleTo }, args); }); }; $.fn.animateCircularPath = function(angleFrom, angleTo, radius, offsetX, offsetY, duration, easing, complete) { var args = $.speed(duration, easing, complete); return this.each(function(i, e) { args.complete = $.proxy(args.complete, e); args.step = function(now) { var rad = now * Math.PI / 180; $(e).css({ top: Math.sin(rad) * radius + offsetY, left: (1 + Math.cos(rad)) * radius + offsetX }); }; $({ deg: angleFrom }).animate({ deg: angleTo }, args); }); }; var left = $() , right = $() , speed = 4000 , currentAngle = 0 , dropAreas = $('.drop-area') , dropAreaLeft = $('.drop-area-left') , dropAreaRight = $('.drop-area-right') , level = $('.level') , easing = 'easeOutElastic' , levelRadius = 80 , halfLevelWeight = 50 , plummetWeight = 100 , plummetOffsetTop = parseFloat(dropAreas.css('top')) , plummetDistance = 10; function animate() { var leftWeight = halfLevelWeight + left.length * plummetWeight , rightWeight = halfLevelWeight + right.length * plummetWeight , angle = (rightWeight - leftWeight) / (rightWeight + leftWeight) * 90; level.animateRotate(currentAngle, angle, speed, easing); var offset = plummetOffsetTop; left.each(function() { $(this).animateCircularPath(180 + currentAngle, 180 + angle, levelRadius, 0, offset, speed, easing); offset += plummetDistance + plummetOffsetTop; }); offset = plummetOffsetTop; right.each(function() { $(this).animateCircularPath(currentAngle, angle, levelRadius, 0, offset, speed, easing); offset += plummetDistance + plummetOffsetTop; }); offset = plummetOffsetTop + left.length * (plummetDistance + plummetOffsetTop); dropAreaLeft.animateCircularPath(180 + currentAngle, 180 + angle, levelRadius, 0, offset, speed, easing); offset = plummetOffsetTop + right.length * (plummetDistance + plummetOffsetTop); dropAreaRight.animateCircularPath(currentAngle, angle, levelRadius, 0, offset, speed, easing); currentAngle = angle; } $('.plummet').draggable({ revert: 'invalid', start: function(e, ui) { dropAreas.show(); }, stop: function(e, ui) { dropAreas.hide(); } }); dropAreas.droppable({ drop: function(e, ui) { ui.draggable.css({ left: $(this).css('left'), top: $(this).css('top') }).draggable('disable'); if ($(this).hasClass('drop-area-left')) { left = left.add(ui.draggable); } else { right = right.add(ui.draggable); } animate(); } }); .container { height: 300px; left: 100px; position: absolute; top: 100px; width: 200px; } .container * { box-sizing: border-box; } .base { border: 1px solid; bottom: 0; height: 10px; left: 50px; position: absolute; width: 100px; } .stand { border: 1px solid; height: 300px; position: absolute; left: 95px; top: 0; width: 10px; } .level { border: 1px solid; height: 10px; left: 0; position: absolute; top: 0; width: 200px; } .drop-area { border: 1px dashed; display: none; height: 40px; position: absolute; top: 40px; width: 40px; } .drop-area-left { left: 0; } .drop-area-right { right: 0; } .plummet { border: 1px solid; bottom: 0; cursor: pointer; height: 40px; position: absolute; width: 40px; } .plummet-1 { right: 0; } .plummet-2 { right: -50px; } .plummet-3 { right: -100px; } .plummet-4 { right: -150px; } .ui-droppable-hover { border: 2px solid; } .ui-draggable-disabled { cursor: default; }


Записать в файл то, что процедура ввыводит на консоль

У меня вызывается метод.
public void doSomethingElse() { Debug.WriteLine(color); }
Сам метод выводит на консоль строку. Как мне после вывода строки на консоль, выведенную информацию записать в файл. Изначально переменную не могу записать в файл так как выполняю юнит тесты.


Ответ

У механизмов отладочного вывода (Debug.WriteLine) и трассировки (Trace.WriteLine) есть стандартные способы перенаправления - Trace Listeners.
По умолчанию вывод Debug.WriteLine уходит вникуда, т.к. ни одного Trace Listener-а для него не задано. При отладке сам отладчик (студия) добавляет Trace Listener, который перенаправляет вывод в окно отладчика (Output), а вовсе не на консоль.
Так что вам не надо перенаправлять вывод на консоль в файл. Вам нужно просто добавить стандартный TextWriterTraceListener в Debug.Listeners и вы получите копию отладочного вывода в файле. Вот минимальный код:
using System.Diagnostics;
namespace ConsoleApp3 { class Program { static void Main(string[] args) { // в инициализации тестов, один раз Debug.Listeners.Add(new TextWriterTraceListener("log.txt"));
Debug.WriteLine("test");
// после прогона тестов // чтобы записать буфер на диск и не потерять хвост лога Debug.Flush(); } } }
При трассировке (использовании Trace.WriteLine) listener-ы можно задавать прямо в конфиге, это достаточно подробно расписано в howto в MSDN


Trace.TraceInformation("Test message."); // You must close or flush the trace to empty the output buffer. Trace.Flush();

HTML-письма - как правильно подключить шрифты

Есть шрифт Bender - нужно подключить в верстку. Как правильно это сделать в html-письме?


Ответ

В почтовых рассылках допускается использование только стандартных шрифтовых наборов, которые присутствуют на всех устройствах. Представляю вашему вниманию список безопасных шрифтов, которые есть на всех устройствах.
font-family: Arial, Helvetica, sans-serif; font-family: 'Arial Black', Gadget, sans-serif; font-family: Georgia, serif; font-family: 'MS Sans Serif', Geneva, sans-serif; font-family: 'MS Serif', 'New York', sans-serif; font-family: Tahoma, Geneva, sans-serif; font-family: 'Times New Roman', Times, serif; font-family: 'Trebuchet MS', Helvetica, sans-serif; font-family: Verdana, Geneva, sans-serif; Таким образом, эти шрифты можно использовать в рассылках без страха и риска. Если вы все же хотите использовать совсем нестандартные шрифты через правило @font-face, то будьте внимательными, это правило работает только в IOS, Google mail и Android 4 (Gmail).
источник
P.S: вот такая конструкция в head позволяет гугл шрифты подключить, но за поддержку не скажу:




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

Переменные в регулярных выражениях

Господа, шаблон рег. выражения состоит из трех частей - переменная, рег. выражение, переменная, например stringBefore + @"([\w]+)" + stringAfter Всё бы хорошо, но в stringAfter помимо букв есть открывающая скобка и Regex думает, что это часть регулярного выражения, и поэтому выкидывается ошибка "Нет парных закрывающих скобок".
Как сделать чтобы переменные распознавались как обычный текст?


Ответ

Используйте Regex.Escape()
Преобразует минимальный набор символов (\, *, +, ?, |, {, [, (, ), ^, $, , # и пробел), заменяя их соответствующими escape-кодами. При этом обработчику регулярных выражений дается команда интерпретировать эти символы буквально, а не как метасимволы.
Пример объявления:
var reg = new Regex($@"{Regex.Escape(stringBefore)}(\w+){Regex.Escape(stringAfter)}");
В старших версиях C# можно использовать аналогичный
var reg = new Regex(string.Format(@"{0}(\w+){1}", Regex.Escape(stringBefore), Regex.Escape(stringAfter)));

Сортировать список и удалить элементы, по которым велась сортировка

Имеется такой словарь:
{'L': [(568.0, 'John'), (208.0, 'Jack'), (88.0, 'Leopold'), (448.0, 'Sonny'), (328.0, 'Julian')], 'R': [(1478.0, 'Diana'), (1238.0, 'Din'), (998.0, 'Mary'), (1118.0, 'Veronica'), (1357.0, 'Richard')]}
С помощью этого кода:
for key in dictionary: dictionary[key].sort() for i in range(len(dictionary[key])): dictionary[key][i] = dictionary[key][i][1]
Он сортируется и становится вот такого вида:
{'L': ['Leopold', 'Jack', 'Julian', 'Sonny', 'John'], 'R': ['Mary', 'Veronica', 'Din', 'Richard', 'Diana']}
То есть производится сортировка по возрастанию чисел (первых элементов кортежей), после чего эти числа удаляются. Каким образом можно еще сортировать эти списки, чтобы получился точно такой же результ? Мой код просто вырви глаз, если честно.


Ответ

мне кажется использовать тут .items() или .values() излишне
{k: [l[1] for l in sorted(_dict[k])] for k in _dict}
дополню коментарием по ответу Ilia w495 Nikitin
чем плохо использование lambda в map - это всегда длинее другого варианта
# сравните result_list = map(lambda value: value[1], value_list) result_list = list(result_list) # тоже, но без map короче на 5 символов result_list = [value[1] for value in value_list] # даже если записать for+append в одну строку, все равно короче result_list = [] for value in value_list: result_list.append(value) # если функция для map уже определена(как str), тут и следует использовать map print('
'.join(map(str, result_list)))

Безопасно ли хранить информацию в Session? ASP.Net MVC, C#

Добрый день, граждане! Работаю, вот, с ASP.Net. Имеется здесь объект, представляющий текущую сессию пользователя, в него можно записывать информацию любых видов и получать по ключу (короче, нечто вроде Dictionary). Но вот безопасно ли это делать? Может ли пользователь перехватить оттуда хранимую информацию? И, если да, какие есть аналоги?


Ответ

В браузере нету содержимого самой сессии. Пользователю передается только идентификатор сессии, который записывается в куки. Каждый пользователь может спокойно посмотреть свои куки и изменить.
Безопасно ли это? Конечно нет, но безопаснее куков. Все что передается пользователю от сервера или к серверу можно перехватить иди даже проще случай, например, пользователь может скопировать идентификатор сессии и передать его другому человеку.
Главное отличие сессии от куков это то, что при использовании сессий вся информация хранится на сервере, а у клиента имеется только идентификатор. У куков вся информация хранится у клиента.
Так же сессии хранятся определенное количество времени. Настраивается на веб-сервере. Например, если по истечении 20 минут не было обращения, то сессия автоматически удаляется.
Сеансы поддерживают объекты любого типа, включая специальные, создаваемые самим разработчиком типы данных. Управление сеансом не является частью HTTP-стандарта. Поэтому для отслеживания информации сеанса и ее привязки к соответствующему ответу ASP.NET приходится выполнять дополнительную работу. Для отслеживания сеанса используется уникальный 120-битовый идентификатор, который генерируется по патентованному алгоритму. Этот идентификатор является единственным фрагментом информации, который передается между веб-сервером и клиентом.
Так же можно выбрать где хранить объекты сессии. Это может быть объект в памяти, таблицы в б/д с специальным названием ASPState или Windows-служба.

Подробную информацию о сессиях, как их использовать, настроить или выбрать метод хранения можно узнать на ProfessorWeb

Задача о ранце. Как сократить память?

Получил задание решить классическую задачу о ранце. Есть N предметов, у каждого предмета есть вес и цена, есть ранец, который выдерживает определённый вес. Задача унести как можно больше в денежном эквиваленте(вывести максимальную сумму денег). Задачу я решил, но в одном из 10 тестов на специальном сайте я получил "ошибку" Out of memory, что означает, что нужно как-то уменьшить количество памяти. Как я понял я могу использовать то, что мне не нужен список предметов, только суммарный вес, но как это реализовать я не знаю.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using CodEx;
namespace ranec { class Program { static long max, count; static long[] vah; static long[] cen; static void Main(string[] args) { max = long.Parse(Console.ReadLine()); count = long.Parse(Console.ReadLine()); vah = new long[count]; cen = new long[count]; for (int i = 0; i < count; i++) { vah[i] = Reader.Console().Int(); cen[i] = Reader.Console().Int(); } long d = bag(vah, cen, max); Console.WriteLine(d); Console.ReadLine(); }
//вот сама процедура поиска, vaha - массив весов, ceny массив цен, _max - максимальный вес, который выдерживает рюкзак //вопрос в том, какая часть массива pl мне не нужна?
static long bag(long[] vaha, long[] ceny, long _max) { long n = vaha.Length; long[,] pl = new long[_max+1, n+1]; for (int j = 1; j <= n; j++) { for (int i = 1;i <= _max; i++) { if (vaha[j-1] <= i) { pl[i, j] = Math.Max(pl[i, j-1], pl[i-vaha[j-1], j-1] + ceny[j-1]); } else { pl[i, j] = pl[i, j-1]; } } } return pl[_max, n]; } } }


Ответ

При заполнении матрицы pl вы обращаетесь только к предыдущей строчке. Отсюда и первый вариант оптимизации - хранить в памяти только две строчки, а не всю матрицу целиком.
Но можно пойти дальше - хранить в памяти всего одну строчку, делая вычисления сразу в ней. Так можно делать по той причине, что при вычислении pl[i,j] не бывает обращений к элементам с большими индексами - а потому если вычислять справа-налево, то дополнительная память для хранения "старых" значений никогда не понадобится. Просто уберите из своего алгоритма второй индекс у массива и разверните внутренний цикл в обратную сторону.
Тело цикла будет выглядеть примерно вот так (ветку else я выкинул из-за ее тривиальности):
if (vaha[j-1] <= i) { pl[i] = Math.Max(pl[i], pl[i-vaha[j-1]] + ceny[j-1]); }
Или, после дальнейших упрощений,
if (vaha[j-1] <= i && pl[i] < pl[i-vaha[j-1]] + ceny[j-1]) { pl[i] = pl[i-vaha[j-1]] + ceny[j-1]; }
Именно так и выглядит классический алгоритм рюкзака.

События js, динамические элементы

Перемещаю div при помощи js в разные места (переменная > remove() > append()), есть клик события на внутренние элементы. При изменении положения дива клик перестает работать, внутренние элементы при этом не меняют класс, на который повешено событие, — как это исправить?
Пример на jsFF
$(".remove").click(function (){ var removeBox = $(".holder"); $(".holder").remove(); $(".parent2").append(removeBox); });
$(".holder > div").click(function () { console.log("Клик"); });


Ответ

Согласно справке по функции .remove()
all bound events and jQuery data associated with the elements are removed. To remove the elements without removing data and events, use .detach() instead.'

все привязанные обработчики и данные ассоциированные с элементами будут удалены. Для удаления элементов без удаления данных и обработчиков используйте .detach()

$(".remove").click(function() { var removeBox = $(".holder").detach(); $(".parent2").append(removeBox); }); $(".holder > div").click(function() { console.log("Клик"); });

1111

Свои References, но в подпапке

Есть решение с двумя проектами
DLL библиотека WPF приложение, использующее DLL в References
При компилировании проекта WPF, DLL помещается в папку с EXE. Однако по независимым от меня причинам необходимо что бы WPF приложение искало эту DLL в папке [номер версии] в папке приложения т.е.:
Если приложение находится в папке c:\MyProject\project.exe, а у файла версия 1.0.3.24 значит DLL будет находиться в c:\MyProject\1.0.3.24\MyLibrary.dll
Вот моё решение:
Свойство Build Action у App.xaml установил в Page, а в App.xaml.cs добавил код.
[STAThread] public static void Main() { try { //Берём Assembly приложения System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly(); //Берём папку приложения string appDirectory = System.IO.Path.GetDirectoryName(assembly.Location); //Берём версию приложения string appVersion = System.Diagnostics.FileVersionInfo.GetVersionInfo(assembly.Location).FileVersion; //Вычисляем папку с DLL string dllpatch = System.IO.Path.Combine(appDirectory, appVersion); //Берем переменную окружения PATH string environmentPATH = Environment.GetEnvironmentVariable("PATH"); //Устанавливаем переменную окружения PATH Environment.SetEnvironmentVariable("PATH", environmentPATH + ";" + dllpatch, EnvironmentVariableTarget.Process); //Запускаем приложение var application = new App(); application.InitializeComponent(); application.Run(); } catch (Exception ex) { //Эта строка не срабатывает, Exeption не отлавливается System.Diagnostics.EventLog.WriteEntry("MyApplication", ex.Message + "
" + ex.StackTrace, System.Diagnostics.EventLogEntryType.Error); } }
Однако, при запуске проекта всё нормально, но как только я помещаю dll в вышеуказанную папку try catch не срабатывает, приложение сваливается в исключение, а лог винды выводиться:
Приложение: project.exe Версия платформы: v4.0.30319 Описание. Процесс был завершен из-за необработанного исключения. Сведения об исключении: System.IO.FileNotFoundException в MyNameSpace.App.Main()


Ответ

Попробуй воспользоваться codeBase в app.config.

Еще есть . В нем можно указывать директории для поиска сборок.

Как запустить команды Git из Java?

Я могу запускать команды, git add, git commit, прямо из Git. Но есть ли какие-либо методы, чтобы я мог запускать команды непосредственно из java.


Ответ

Не знаю как это описать на русском. Но в Java есть класс Runtime для соответствующей работы.
У него есть метод getRuntime(), который возвращает соответствующий приложению Runtime, а также есть метод exec(String command), который в отдельном процессе запускает команду, представленную переданной строкой. Возвращаемый объект :py:class::java.lang.Process и может быть использован для управления выполнением этого процесса. Собственно их и можно использовать. Пример:
Runtime.getRuntime().exec("git add");
Естественно с try/catch и прочими проверяющими конструкциями

P.S.
Нашел описание методов на русском, чтоб ознакомиться проще было. Источник ilnurgi1.ru
class java.lang.Runtime
getRuntime() - Возвращает соответсвующий приложению Runtime
exit(int status) public void - Осуществляет завершение программы с кодом завершения status (при использовании этого метода особое внимание нужно уделить обработке исключений - выход будет осуществлен моментально, и в конструкциях try-catch-finally управление в finally передано не будет)
gc() public native void - Сигнализирует сборщику мусора о необходимости запуска
freeMemory() public native long - Возвращает количество свободной памяти. В некоторых случаях это количество может быть увеличено, если вызвать у объекта Runtime метод gc()
totalMemory() public native long - Возвращает суммарное количество памяти, выделенное Java машине. Это количество может из изменяться даже в течении одного запуска, что зависит от реализации платформы на которой запущена Java машина. Так-же, не стоит закладываться на объем памяти, занимаемой одним определенным объектом - эта величина так же зависит от реализации Java машины.
loadLibrary(String libname) public void - Загружает библиотеку с указанным именем. Обычно загрузка библиотек производится следующим образом: в классе, использующем native реализации методов, добавляется статический инициализатор, например:
static { System.loadLibrary("LibFile"); }
Таким образом, когда класс будет загружен и инициализирован, необходимый код для реализации native методов так-же будет загружен. Если будет произведено несколько вызовов загрузки библиотеки с одним и тем-же именем - произведен будет только первый, а все остальные будут проигнорированы.
load(String filename) public void - Подгружает файл с указанным названием в качестве библиотеки. В принципе, этот метод работает так-же как и метод load(), только принимает в качестве параметра именно название файла, а не библиотеки, тем самым позволяя загрузить любой файл с native кодом.
runFinalization() public void - Производит запуск выполнения методов finalize() у всех объектов, этого ожидающих
exec(String command) public Process - В отдельном процессе запускает команду, представленную переданной строкой. Возвращаемый объект :py:class::java.lang.Process может быть использован для управления выполнением этого процесса.

Доступ к полям родительского класса (Рефлексия) - C#

Есть вот такая конструкция, напишу упрощённо:
public partial class A : UserControl {
public class B : A {}
public A(){ var cmbList = C.SelectllControlsByType(this, typeof(ComboBox)); } }
public static class C { ///

/// Выбрать контролы заданого типа /// /// /// private static List SelectllControlsByType(Control rootControl, Type selectionControlType) { return (from field in rootControl.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance) where field.FieldType == selectionControlType select field.GetValue(rootControl) as Control).ToList(); } }
Если инстанциируем контрол класса A, то метод SelectllControlsByType отрабатывает корректно и возвращает (к примеру) список из трёх комбобоксов, которые есть на этом контроле. А если создаем тот же контрол, но через дочерний класс: new A.B(), то метод возвращает пустой список, хотя комбобоксы по прежнему существуют на этом контроле.
Т.е. я так понимаю GetType().GetFields в методе SelectllControlsByType пытаются взять поля класса B, а у него естественно их нет, они есть только у А
Как сделать так, чтобы метод отрабатывал корректно в обоих случаях?


Ответ

Проблема в том, что метод GetFields возвращает закрытые поля лишь текущего класса, но не базовых классов. Поэтому вы закономерно получаете (пустой) список полей класса B.A
Вам нужно подняться вверх по дереву наследования:
static List SelectllControlsByType(Control rootControl, Type selectionControlType) { IEnumerable GetTypeChain(Type from, Type to) { for (var t = from; t != to; t = t.BaseType) yield return t; }
IEnumerable GetPrivateFields(Type t) => t.GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
var allFields = GetTypeChain(rootControl.GetType(), typeof(Control)) .SelectMany(GetPrivateFields);
return (from field in allFields where field.FieldType == selectionControlType select field.GetValue(rootControl) as Control).ToList(); }

Есть ли разница между отображением картинки и base64

Делаю галерею. Хранить картинки на сервере мне проще в base64. Есть ли разница при отображении картинки в html между указанием в атрибуте src пути до картинки или подстановкой в этот тег строки base64 с точки зрения производительности или еще чего нибудь?


Ответ

хранить на сервере, это в базе? если у вас более менее большие изображения, то сохраняйте как статичные файлы. зачем каждый раз гонять туда сюда контент файлов через коннекшен базы? она и так большую часть нагрузки на себя берет.
если вы используете base64, то
изображения не кешируются, а отправляются вместе с HTML. Т.е юзер будет ждать пока загрузится 5 мегабайт страницы и отрендерится. Вместо того, чтобы отобразить контент и стили, а все остальное параллельно догружать (причем браузеры умеют перед полной загрузкой изображения показывать превьюшку) можно использовать серверный GZIP, в много раз уменьшая размер получаемого контента. статичные файлы в целях оптимизации принято отдавать на CDN. он выгружает контент с более близкого сервера, ускоряя загрузку. также ставят NGINX (только либо перед апачем), который быстро работает с стат. файлами. в base64 этот вариант не работает

Смена раскладки на linux через python

Собственно как это делать на Windows в интернете решение есть, но вот как сменить на linux ?


Ответ

Вот я тормоз...Если xdo.Xdo().send_keysequence_window(xdo.CURRENTWINDOW, b"alt+shift") не работает и если я уже пользуюсь pyautogui,то неужели было трудно додуматься до такого ???
import pyautogui as pikapika #pip install pyautogui pikapika.hotkey('shift', 'alt')

Immutable объект в Java

В java все объект могут быть mutable и immutable. Понятно, что, например, строка является immutable. Но если я хочу создать собственный immutable тип, то какие требования он должен выполнять ?
У меня есть такой пример:
public class ImmutableObject {
private final String string; private final Date date;
public ImmutableObject(String string, Date date) { this.string = string; this.date = date; }
public Date getDate() { return new Date(date.getTime()); }
public String getString() { return string; }
}
Могу ли я его считать неизменяемым ? Обязательно ли поля должны быть final ? И если одно из полей, например строка, не будет final, то объект данного класса можно считать неизменным ? Учитывает ли данный класс все подводные камни многопоточности ?


Ответ

Да, поля обязательно должны быть final
Я бы не поставил знак равенства между между Immutable объектом и объектом, имеющим методы только для чтения. Дело в том, что в качестве оптимизации, компилятор может запросто переставлять строки с инструкциями, это так называемый reordering. В результате может получиться так, что ваш объект будет доступен из других потоков, но его переменные могут не быть проинициализированы. В однопоточных приложениях это в принципе не страшно, но вот если вы работаете в многопоточной среде, то final защитит ваши переменные от таких перестановок.
Теперь по существу ваших вопросов:
Да, объекты вашего класса можно считать неизменяемым. В многопоточной среде обязательно. Если строка будет не final, то такой объект уже не Immutable.

Импорт в коде, который выполняется много раз

Разбирая чужой код, наткнулся на подобный фрагмент:
@property def foo(self): from some_module import something return something['some_param']
Насколько хорошим решением является использование импорта в коде, который должен исполняться многократно и быстро? (а ведь тяжёлые функции не рекомендуется оформлять как propety).
Будет ли импорт каждый раз выполняться при вызове этого свойства или интерпретатор в таких случаях выполняет импорт только один раз?


Ответ

Хотя интерпретатор кэширует модуль после 1 импорта, 2 импорт все равно не будет выполняется быстро. Поэтому, а также для увеличение понятности кода рекомендуют весь импорт помещать наверх а не в функции. Поэтому код:
@property def foo(self): from some_module import something return something['some_param']
неправильный. from some_module import something надо поднять наверх. Хотя стоит заметить что в отдельных случаях (решение проблем импорта например) такой код может быть "оправдан".
P.S: Замер скорости импорта.
Код:
from timeit import timeit
def slow(): for i in range(1000): import os
def fast(): import os for i in range(1000): pass
def stub(): for i in range(1000): pass
Замеры:
timeit("slow()", "from __main__ import slow, fast, stub", number=1000)
3.3150182569997924
timeit("fast()", "from __main__ import slow, fast, stub", number=1000)
0.15638045699961367
timeit("stub()", "from __main__ import slow, fast, stub", number=1000)
0.15032413299923064

Магическое изменение значения переменной после scanf

Всем привет. Столкнулся с какой-то абсолютно мистической проблемой.
Есть код на Си:
int main(int argc, char const *argv[]) { unsigned int a, A = 0; unsigned short tmp = 0; scanf("%u", &a); // вводим значение, будем считать, что 3 //a = 3; for (int i = 0; i < a; i++) { printf("--%u
", a); // a == 3 scanf("%u", &tmp); printf("--%u
", a); // внезапно а == 0 A |= 1 << tmp; }
return 0; }
Примечание: Если раскомментировать строку //a = 3 и убрать первый scanf, все адекватно работает.
Надеюсь, из комментариев в коде все понятно. Переменная a в цикле каким-то магическим образом меняет свое значение после строки scanf("%u", &tmp);
Ломаю голову уже часов 5, поэтому прибежал к вам. В чем вообще тут проблема может скрываться?


Ответ

Попробуйте написать не scanf("%u", &tmp);, а scanf("%hu", &tmp);: у вас же short int, а не int...

char[] в Character[]

Как перевести массив char[] к его оболочке Character[] для дальнейшей сортировки в обратном порядке? Делаю по аналогии как с int -> Integer:
int[] array = {...}; Integer[] newArray = Arrays.stream(array).boxed().toArray(Integer[]::new); Arrays.sort(newArray, Collections.reverseOrder());
Но с char так не работает:
Character[] newArray = Arrays.stream(array).boxed().toArray(Character[]::new); Arrays.sort(newArray, Collections.reverseOrder());


Ответ

Да, для примитивов char есть такая проблема. Можно например так её решить:
char[] array = {'a','c','b'}; Character[] newArray = IntStream.range(0, array.length) .mapToObj(i -> array[i]) .toArray(Character[]::new); Arrays.sort(newArray, Collections.reverseOrder());
c, b, a

Где объявлять вспомогательные функции?

К примеру, у меня есть класс, который делает WMI запросы, там часто надо преобразовывать QString к BSTR, поэтому я хочу написать функции преобразования. Где мне их лучше объявлять, в этом же классе, если да, то private или public? Создать namespace с двумя функциями только для этого класса? Создать общий namespace для всех функций преобразования, и, пока что, записать туда только две эти функции? Объявить их глобально в хедере этого класса?


Ответ

Как пишет Скотт Мейерс в своей книге «Эффективное использование C++»:
Предпочитайте функциям-членам функции, не являющиеся ни членами, ни друзьями класса. Это повышает степень инкапсуляции и расширяемость, а также гибкость упаковки функциональности.
Если хотите ознакомиться с этим правилом детальнее - см. стр. 105 вышеупомянутой книги.
Если Ваши функции выполняют преобразование и не требуют доступа к закрытам данным-членам или методам Вашего класса - пользуйтесь этим советом, поскольку, если свободная функция способна обеспечить ту же функциональность, что и метод класса, то предпочтительней является свободная функция, поскольку она увеличивает степень инкапсуляции данных. А это уже одна из особенностей, ожидаемых от ООП программ.
Идея использовать namespace, в который Вы поместите свой класс и эти функции преобразования, хорошая, явно лучше, чем подвесить их в глобальной области видимости.