BAT: Неизвестные факты из жизни пакетных файлов

Многие слышали про bat-файлы. Но не все знают что:

  1. Помимо BAT, были ещё CMD, WSH (Win­dows Script Host с поддержкой аж двух языков — JScript и VBScript), а чуть позже появился Pow­er Shell. JScript и VBScript интересны тем, что были намного сложнее и непонятнее BAT. Но и на них писали.
  2. BAT работали ещё в DOS-е, поэтому его выполняет command.com. А вот CMD — это более новый формат, его выполняет cmd.exe. Поэтому лучше использовать расширение CMD.
  3. BAT и CMD не понимают вложенный if (то есть if может быть только на 1 уровне). Поэтому чтобы сделать условия, приходится рисовать блок-схему и расставлять везде GO TO. Да-да, ту самую блок-схему, которую ещё во времена “Мифического человеко-месяца” рисовали уже после завершения проекта.
  4. @echo off нужно, чтобы bat-ник не писал вызовы на экран.
  5. rem — это строка комментария.
  6. Если написать в файле script1.bat строку script2 (причём script2.bat существует — т.е. мы вызываем его как команду), то script2.bat запустится, а script1.bat — прекратит выполнение. Чтобы не прекращал, надо писать EXEC script2.
  7. Переход в директорию, где лежит скрипт — cd %~dp0.
  8. Можно поставить cyg­win и наслаждаться *nix-овой командной строкой под Win­dows. Кстати, там можно вкладывать сколько угодно If-ов. А ещё можно поставить ActivePerl. К сожалению, писать скрипт прямо в командной строке у Perl под Win­dows не получится — не такой стандарт для кавычек.
  9. Параметры командной строки лежат в переменных  %1..%9. %0 — имя скрипта (без расширения). %10 и больше — нет.
  10. Включать-выключать сервисы из пакетных файлов — это просто:  Проверить:
    SC QUERY "XService" | find "RUNNING"
    IF not "%ERRORLEVEL%" == "0" GOTO StartService
    ................
    :StartService

    Запустить:

    NET START "XService"

    Остановить:

    NET STOP "XService"
  11. Откомпилировать и запустить пример для wxWid­get:
    • Cоздаём в каталоге, прописанном в AUTOEXEC, вот такой makesample.cmd
      @echo off
      make -f makefile.bcc
      for %%f in (*.exe) do start %%f
      exit
    • Заходим в каталог с файлами
    • Запускаем (нужно, чтобы был установлен компилятор make)

 

C++: Вопросы на собеседовании

Вопросы на собеседовании по С++” — один из самых популярных запросов, по которым находят этот блог.

А значит, настало время расширить этот постинг.

Т.к. такие списки периодически пропадают из Сети, я буду делать свой — с приложенными ответами.

Итак, понеслось:

Напоследок — картинка от jia3ep-а.

C#: List> в DataGrid

Когда-то List<> скидывали в Data­Grid вот так:

dataGridView.DataSource = null;
dataGridView.DataSource = list;

Но увы — если загружать list таким образом, в ViST2008 мы будем получать Index­Out­OfRange­Ex­cep­tion каждый раз, когда попытаемся его выделить. 🙁

Поэтому надо привязывать Bind­ingList, который умеет обновляться автоматически. А обновлять только ширину колонок:

dataGridView.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCellsExceptHeader);

JavaScript: Случайные элементы массива

Родилось из C#-овой, но на JavaScript наглядней.

Нужно выбрать из массива N случайных элементов. Как это сделать быстро?

Если длина массива <= N — это очевидно. А если нет? Сначала склонируем массив:

Object.prototype.clone = function() {
var newObj = (this instanceof Array) ? [] : {};
for (i in this) {
  if (i == 'clone') continue;
  newObj[i] = (this[i] && typeof this[i] == "object") ? this[i].clone() : this[i];
  return newObj;
};

Потом создадим новый массив и скопируем в него нужное число элементов, а из оригинала удалим:

function selectRemoveAdd(arr, max)
{
 var arrLength = arr.length;
 if(max >= arrLength)
  return arr.clone();
 var newArray = [];
 var cloneArray = arr.clone();
 var i = 0, newPos = 0;
 while(i++ < max)
 {
  newPos = getRandom(arrLength);
  newArray.push(cloneArray[newPos]);
  cloneArray.splice(newPos, 1);
  arrLength--;
 }
 return newArray;
}

Такой вариант обычно предлагают на форумах. Но зачем создавать ещё одни массив? Можно взять исходный и удалить всё лишнее:

var arrLength = arr.length;
 if(max >= arrLength)
  return arr.clone();
 var newArray = arr.clone();
 while(arrLength-- > max)
  newArray.splice(getRandom(arrLength), 1);
 return newArray;

Какой вариант быстрее? Правильный ответ, что быстрее оба, но по-разному. Если N меньше arr.length / 2, то первый, если больше — то второй. Поэтому самый красивый и правильный способ — это:

function selectRemoveOnly(arr, max)
{
 var arrLength = arr.length;
 var newArray = arr.clone();
 while(arrLength-- > max)
   newArray.splice(getRandom(arrLength), 1);
 return newArray;
}
function selectRemoveAdd(arr, max)
{
 var arrLength = arr.length;
 var newArray = [];
 var cloneArray = arr.clone();
 var i = 0, newPos = 0;
 while(i++ < max)
 {
  newPos = getRandom(arrLength);
  newArray.push(cloneArray[newPos]);
  cloneArray.splice(newPos, 1);
  arrLength--;
 }
 return newArray;
}
function selectOptimised(arr, max)
{
 if(max >= arr.Length)
  return arr.clone();
 if(max <= arr.length / 2)
  return selectRemoveAdd(arr, max);
 else
  return selectRemoveOnly(arr, max);
}

И работать будет просто замечательно:

JavaScript: Объекты и необъекты

Говорят, во всём семействе ECMAScript все переменные — псевдообъекты.

Так вот, это неправда.

В JavaScript, например, всего 6 типов объектов:

null, unde­fined, num­ber, string, boolean и object

а значит, записать в числовую переменную новое свойство — нельзя.

Вызывая оператор “.” для num­ber, string, boolean мы просто создаём ещё один object, который получает новое свйоство, а потом записывается в никуда. Правило конвертации простое:

  • если присвоили object — оставляем как есть
  • если присвоили unde­fined, кидаем excep­tion
  • во всех прочих случаях — new Number(input), new String(input) или new Boolean(input)

JavaScript: быстрый floor и приведение объектов

Чудесное от Михаила Барановского:

В JavaScript можно писать через степень:

var a = 120000; // make it shorter?
var a = 12e4;

 

var a = Math.floor(b);
// если b всегда > 0, можно сократить до:
var a = ~~b;

Легко получать текущую дату:

var date = +new Date;

Это работает, потому что + дёргает val­ue­of.

var a = new Boolean(false); // how to quickly check if (a)?
alert(typeof a); // "object"
alert(!!a); // always true, because a is an object
alert(!!+a);
// right result, because "+" is calling valueOf
// method and convert result to number "0..1"
alert(a>0); // even shorter

C#: Enum в ComboBox

Сбросить Enum в Com­bobox можно одной строкой:

comboBox.DataSource = Enum.GetValues(typeof(AnEnumType));
comboBox.SelectedItem = AnEnumType.Value