Page 70 of 99

Posted: Mon Nov 16, 2015 2:31 pm
by Skif_off
SFC wrote:> P.S. По хорошему ещё, наверное, выпиливать аббревиатуры и сокращения (dr. и прочее).

Не думаю. Пусть будет общее правило: удалять знаки препинания и сравнивать. Абревиатуры будут в словаре - и оно будет работать так как сейчас есть.
"Dr. Watson" превратиться в "Dr" и "Watson", как-то это не так, хотя да, по идее можно убрать, добавив "dr" в словарь.
SFC wrote:По идее или fr554 должно остаться или fr. Тут я сам не соображу.
Если текст будет не художественный, то, например, "RFS207-9, RFS2079" превратиться в "rfs", что вряд ли будет понятно сразу, тогда лучше не убирать цифры.
SFC wrote:Замечание:
От hgfh остается hgf
т.е. съедается последний символ. И так у любого последнего слова.
Прошу прощения, не заметил, это из-за

Code: Select all

AkelPad.ReplaceSel(pText.substr(0, pText.length - 1));
Убрал метод substr().
SFC wrote:Я добавил третью строку:
nod's far
nod's - исчезает, а должен остаться. И от hgfh остается hgf все равно
Вроде исправил, это от первых вариантов осталось, "don't" превращалось в "don" и "t", что неправильно.
SFC wrote:Вот так вроде нормально делает первый шаг - приводит в столбец:
См. строку 46

Есть проблема: как оставить слова с цифрами, подождём, может быть, у кого-нибудь ещё будут идеи.

Posted: Mon Nov 16, 2015 4:26 pm
by Kley
SFC wrote:Когда читаешь англ текст встречаются незнакомые слова. Хотелось бы не читая текста сразу определить какие слова незнакомые чтобы заранее их выучить и уже спокойно читать текст.
Ключевое "слова". Зачем выучивать fr554? Это не слово, не англ. слово, не русское...
Может стоит создать еще один файл (файл исключений), куда юзер будет вносить слова, типа "the, fr, do, not" - "знакомые" со школьной скамьи. Эти слова удалять до всей обработки.
p.s.

Code: Select all

AkelPad.ReplaceSel(pText.substr(0, pText.length - 1));
строка удаляла союзы и все одиночные символы

Posted: Mon Nov 16, 2015 4:33 pm
by SFC
Skif_off
Все работает. Давайте пока на этом остановимся.
Подумаем. По горячим следам - все работает идеально вроде. Позже накоплю статистику - выскажу критику если она будет конечно.

Слова с цифрами убирает - так и должно быть. Kley прав.
Слова из одной буквы убирает - это также есть ОК.

Создавать еще один файл = исключений нет смысла. Это и есть единственный файл dictionary со всеми словами которые надо убирать и т.д.

Большое спасибо :)

Добавлено:

Великолепно. Сейчас поместил в словарь Longman 9000. и проверил новость от BBC. Результат ожидаем.

Спс!!!

Posted: Mon Nov 16, 2015 4:46 pm
by Skif_off
Kley wrote:

Code: Select all

AkelPad.ReplaceSel(pText.substr(0, pText.length - 1));
строка удаляла союзы и все одиночные символы
Одиночные символы, так понимаю, убираются здесь

Code: Select all

  if (aWordList[i].length > 1)
    pText += aWordList[i] + "\r";
substr() возвращает не всю строку.

Posted: Mon Nov 16, 2015 4:49 pm
by Kley
Skif_off
"Заказчик" доволен, ну и слава Богу.
SFC wrote:чтобы сделать неск копий скрипта на случаи разных языков
Хотя вряд ли он пробовал с "разными языками". Ведь скрипт напрочь удаляет все "нелатинские" символы.

Добавлено.
Skif_off,
извините меня приставучего и торопыгу. Возможно я просто не разобрался, но нужна ли функция Dubl?
GetWords уже просто не добавляет дубли. И pText.sort() тоже она делает.

Posted: Mon Nov 16, 2015 6:47 pm
by Skif_off
Kley
Согласен, в таком виде ни к чему, исправил.
SFC wrote:сделать неск копий скрипта на случаи разных языков.
Как вариант - составить список символов, типа французский (исходя из предположения, что toLowerCase() корректно сработает со всеми буквами):

Code: Select all

[a-z\u0153\u00E0\u00E2\u00E6\u00E7\u00E8\u00E9\u00EA\u00EB\u00EE\u00EF\u00F1\u00F4\u00F9\u00FB\u00FC\u00FF]
Но не знаю, какие языки, брать все по алфавиту - не вариант :)

Posted: Mon Nov 16, 2015 8:52 pm
by KDJ
SFC, Skif_off, Kley
A little simpler code, without sorting (it should work faster):

Code: Select all

var aWord;
var oDict;
var oDupl;
var i;

if (aWord = AkelPad.GetTextRange(0, -1).toLowerCase().match(/[^\s`"\\\|\[\]\(\)\{\}<>,\.;:\+\-=~!#\$%\^&\*\/\?«»\d]+/g))
{
  oDict = GetDictionary();
  oDupl = {};

  for (i = aWord.length - 1; i >= 0; --i)
  {
    if ((aWord[i] in oDict) || (aWord[i] in oDupl))
      aWord.splice(i, 1);
    else
      oDupl[aWord[i]] = true;
  }

  AkelPad.SetSel(0, -1);
  AkelPad.ReplaceSel(aWord.join("\r\n"), -1);
}

function GetDictionary()
{
  var aDict = AkelPad.ReadFile(AkelPad.GetAkelDir(1) + "\\Tools\\dictionary.txt", 0x10 /*OD_ADT_NOMESSAGES*/, 65001 /*UTF-8*/, 0).split(/[\r\n]+/);
  var oDict = {};
  var i;

  for (i = 0; i < aDict.length; ++i)
    oDict[aDict[i]] = true;

  return oDict;
}

Posted: Tue Nov 17, 2015 4:27 pm
by Skif_off
KDJ wrote:without sorting (it should work faster)
But with sorting is more comfortable :)
Words with numbers are not needed and required certain language only (not all words).
My JScript knowledges is bad and now I don't know how better to do :)

Is replace() more fast than splice()? And if the array is very large?

Posted: Tue Nov 17, 2015 5:08 pm
by Kley
Skif_off
Первое сообщение SFC, по этой теме, скопировал несколько сот раз в файл. Получилось ~110 000 строк (файл ~13M).
Ваш скрипт работал буквально пару секунд. Куда уж быстрей :D

Posted: Wed Nov 18, 2015 9:48 pm
by Skif_off
Kley
Вопрос про скорость в значительной мере теоретический, а не про конкретный скрипт: гуглил, но так и не понял, что происходит с массивом при использовании splice(). По идее удаление ячейки в произвольном месте сдвинет ячейки ниже и заставит пересчитать индексы? Тогда с большим массивом понадобится больше ресурсов и выше шанс ошибки, чем при работе со строкой. Гипотетически.

Posted: Thu Nov 19, 2015 8:27 pm
by KDJ
Skif_off
About splice method you can read here: http://www.w3schools.com/jsref/jsref_splice.asp
It seems to me that the operations on long strings (eg. concatenation, replace) are slower than operations on the arrays.
For speed test you can use as text AkelHistory-Eng.txt, English dictionary from PSPad: http://www.pspad.com/en/download.php#dictionary and scripts:

Code: Select all

// Отсюда http://akelpad.sourceforge.net/forum/viewtopic.php?p=29871#p29871 и ниже,
// скрипт http://akelpad.sourceforge.net/forum/viewtopic.php?p=29873#p29873
// 2015-11-16

var nTime = new Date().getTime();
var pText = AkelPad.GetTextRange(0, -1).toLowerCase();
var aWordList = GetWords(pText);
var aDict;

pText = "";

for (i = 0; i < aWordList.length; ++i)
{
  if (aWordList[i].length > 1)
    pText += aWordList[i] + "\r";
}
// Читаем \AkelFiles\Tools\dictionary.txt (в UTF-8 без BOM) и режем в массив
aDict = AkelPad.ReadFile(AkelPad.GetAkelDir(1) + "\\Tools\\dictionary.txt", 0x10 /*OD_ADT_NOMESSAGES*/, 65001 /*UTF-8*/, false).split(/[\r\n]+/);
// Ищем в тексте документа слова из массива, если есть - удаляем
for (var i = 0; i < aDict.length; i++)
{
  if (pText.indexOf(aDict[i]) >= 0)
  {
    oPattern = new RegExp("^" + aDict[i] + "\r+", "gm");
    pText = pText.replace(oPattern, "");
  }
}
// Вставляем отсутствующие слова в документ, заменяя существующий текст
AkelPad.SetSel(0, -1);
AkelPad.ReplaceSel(pText);

WScript.Echo("Time: " + (new Date().getTime() - nTime) + " ms");

// Kley, http://akelpad.sourceforge.net/forum/viewtopic.php?p=29879#p29879
function GetWords(pText)
{
  var aAllWords;
  var nAllWords;
  var aWords = [];
  var sWord;
  var i = 0;

  aAllWords = pText.match(/[^\s`"\\\|\[\]\(\)\{\}<>,\.;:\+\-=~!#\$%^&\*/\?«»]+/g);
  nAllWords = aAllWords ? aAllWords.length : 0;

  if (nAllWords)
  {
    aAllWords.sort();

    while (i < nAllWords)
    {
      sWord = aAllWords[i];
      ++i;
      while ((i < nAllWords) && (sWord == aAllWords[i]))
      {
        ++i;
      }
      // Пропускаем итерацию, если в строке содержится что-нибудь кроме "a-z'"
      if (sWord.search(/[^a-z']+/g) >= 0) continue;
      aWords.push(sWord);
    }
  }
  return aWords;
}

Code: Select all

var nTime = new Date().getTime();
var aWord;
var oDict;
var i;

//if (aWord = AkelPad.GetTextRange(0, -1).toLowerCase().match(/[^\s`"\\\|\[\]\(\)\{\}<>,\.;:\+\-=~!#\$%\^&\*\/\?«»\d]+/g))
if (aWord = AkelPad.GetTextRange(0, -1).toLowerCase().match(/[^\s`"\\\|\[\]\(\)\{\}<>,\.;:\+\-=~!#\$%\^&\*\/\?«»]+/g))
{
  oDict = GetDictionary();

  for (i = aWord.length - 1; i >= 0; --i)
  {
//    if (aWord[i] in oDict)
    if ((aWord[i] in oDict) || (aWord[i].length == 1) || (/[^a-z']+/.test(aWord[i])))
      aWord.splice(i, 1);
    else
      oDict[aWord[i]] = true;
  }

  AkelPad.SetSel(0, -1);
  AkelPad.ReplaceSel(aWord.join("\r"), -1);
}

WScript.Echo("Time: " + (new Date().getTime() - nTime) + " ms");

function GetDictionary()
{
  var aDict = AkelPad.ReadFile(AkelPad.GetAkelDir(1) + "\\Tools\\dictionary.txt", 0x10 /*OD_ADT_NOMESSAGES*/, 65001 /*UTF-8*/, 0).split(/[\r\n]+/);
  var oDict = {};
  var i;

  for (i = 0; i < aDict.length; ++i)
    oDict[aDict[i]] = true;

  return oDict;
}

Posted: Fri Nov 20, 2015 4:46 pm
by SFC
KDJ
Thanks for your work.
But as for me I'd like to get instrument. I got its already.

I tested its both scripts.
dictionary = 7838 words = 71,930 b

1.
file1 = 594,032 b = repeated first test many times.
Skif_off's DIC1 = 384 - 395 ms SORTED
KDJ's DIC2 = 419 - 429 ms and result is NOT SORTED

2.
file2 = 56,663,217 b = LDOCE6 xml code
DIC1 = 37877 - 38295 ms
DIC2 = AkelPAD gets into frozen status. maybe it gets loop encircle
maybe for other data...

I set both scripts for use for sorted or non-sorted results AND COMPARE RESULT for mistakes
Thanks

Posted: Sat Nov 21, 2015 6:26 pm
by KDJ
SFC
This version should work faster (with sorting and without sorting):

Code: Select all

var nChoice;
var nTime;
var aWordAll;
var aWord;
var oDict;
var i;

nChoice = AkelPad.MessageBox(AkelPad.GetMainWnd(), "Do you want to sort the output words?", WScript.ScriptName, 0x23 /*MB_ICONQUESTION|MB_YESNOCANCEL*/);

if (nChoice == 2 /*IDCANCEL*/)
  WScript.Quit();

nTime = new Date().getTime();

if (aWordAll = AkelPad.GetTextRange(0, -1).toLowerCase().match(/[a-z']{2,}/g))
{
  aWord = [];
  oDict = GetDictionary();

  for (i = 0; i < aWordAll.length; ++i)
  {
    if (! (aWordAll[i] in oDict))
    {
      aWord.push(aWordAll[i]);
      oDict[aWordAll[i]] = true;
    }
  }

  if (nChoice == 6 /*IDYES*/)
    aWord.sort();

  AkelPad.SetSel(0, -1);
  AkelPad.ReplaceSel(aWord.join("\r"), -1);
}

WScript.Echo("Time: " + (new Date().getTime() - nTime) + " ms");

function GetDictionary()
{
  var aDict = AkelPad.ReadFile(AkelPad.GetAkelDir(1) + "\\Tools\\dictionary.txt", 0x10 /*OD_ADT_NOMESSAGES*/, 65001 /*UTF-8*/, 0).toLowerCase().split(/[\r\n]+/);
  var oDict = {};
  var i;

  for (i = 0; i < aDict.length; ++i)
    oDict[aDict[i]] = true;

  return oDict;
}

Posted: Sun Nov 22, 2015 2:30 pm
by SFC
KDJ wrote:This version should work faster
Yes. It is faster in 3 - 5 times !!!
And it processes XML file wo problem now also!!!

Many thanks.

Now I can use two scripts for different purposes
word: con‧ces‧sion‧aire
DIC2 sees this word as 4 different words. It is correct for some cases.
DIC1 sees this word as bad word and ignores. It is correct for some cases also.

Some wish:
Remove ask-dialog for ordered/don't ordered - it is complicated

Make pls (ordered/don't ordered) as parameter of call-script. (1/0 f.ex. default = 1) - without any dialog screens

Thanks for ALL.
Many wishes for ALL

Posted: Sun Nov 22, 2015 4:16 pm
by SFC
very sorrrryy
Corections:
My pre- previous test was wrong
I tested scripts by absent dictionary = there was wrong path to dictionary.txt = there were tests without dictionary for both scripts

Now I test correctly both scripts:
file2 = 56,663,217 b = LDOCE6 xml code
DIC1 = 95000 - 96000 ms
DIC2 = 5500 - 6800 ms
That is right

conclusion is not altered

Many thanks