ManiacDC / TypingAid

Word AutoCompletion Utility
http://www.autohotkey.com/board/topic/49517-ahk-11typingaid-v2200-word-autocompletion-utility/
GNU General Public License v3.0
138 stars 45 forks source link

add feature to add weight to words based of recent use #50

Open Theclaws opened 9 years ago

Theclaws commented 9 years ago

New feature request: Add New feature to add weight to words based on how recently it was used.

Theclaws commented 9 years ago

ManiacDC, I have a proof of concept for this. I'll attempt to fork and share with you on github later today. Definitely needs testing and refinement still.

Theclaws commented 9 years ago

ManiacDC, the proof of concept can be found here: https://github.com/Theclaws/TypingAid/tree/Theclaws-patch-for-RecentlyUsedWord-1

To test:

  1. Copy your existing "WordlistLearned.db" file to the files.
  2. Run TypingAid.ahk
  3. Before going any further, use the TypingAid icon in the System Tray and click on the icon. Select the Adhoc Edit menu item. This will add an extra column to the database - use this only once. This was just a quick way to introduce the column.
  4. Use as TypingAid as you would normally. For any word that was added/used today, the system will treat these with a heavier weight using this formula:

If word was used today, then set the weight of the word to the highest of all existing words + give additional weight for words that were most recently used today over words used earlier today

Sample of Modified Query

SELECT word
FROM Words
WHERE wordindexed GLOB 'FO*'
ORDER BY
    CASE WHEN count IS NULL THEN ROWID
        ELSE 'z'
    END
    ,
    CASE WHEN count IS NOT NULL AND date(lastused) = date('now') THEN (select max(count) from Words)+86400 -(strftime('%s',time('now'))-strftime('%s',time(lastused)))
    WHEN count IS NOT NULL THEN ((count - 5) * (1 - ('0.75' / (LENGTH(word) - 2))))
    END DESC
    ,Word LIMIT 200;

Hope this will help you if you decide to implement this feature.

Based on your earlier comments on autohotkey.com, I think you may have some concerns about performance - if so, perhaps such features should be optional for the user to activate/deactivate to allow them to adjust for performance considerations/personal use style.

ManiacDC commented 9 years ago

Nice, I took a quick look at it. I'm going to be unavailable for about a month... but I'll look at it more after that.

Is there a particular reason you used INTEGER for the lastused column datatype rather than NUMERIC? The sqllite datatypes page says to use NUMERIC for datetime: https://www.sqlite.org/datatype3.html

Theclaws commented 9 years ago

Enjoy your time away - I hope it's for leisure!

As for why I used INTEGER, that was rooted in my (mis)understanding from this section of: https://www.sqlite.org/datatype3.html#datetime

1.2 Date and Time Datatype

SQLite does not have a storage class set aside for storing dates and/or times. Instead, the built-in Date And Time Functions of SQLite are capable of storing dates and times as TEXT, REAL, or INTEGER values:

TEXT as ISO8601 strings ("YYYY-MM-DD HH:MM:SS.SSS"). REAL as Julian day numbers, the number of days since noon in Greenwich on November 24, 4714 B.C. according to the proleptic Gregorian calendar. _INTEGER_ as Unix Time, the number of _seconds_ since 1970-01-01 00:00:00 UTC. Applications can chose to store dates and times in any of these formats and freely convert between formats using the built-in date and time functions.

I decided on INTEGER for its support of the "seconds" unit of time measurement, but if any other unit will work equally well, there's no further rationale than that.

Thanks and see you in a month!

ManiacDC commented 9 years ago

Thanks, yep, it's for good reasons :)

I'll read more about it. It's funny because in 2.2 it says to use NUMERIC for datetime...

Theclaws commented 9 years ago

Hi ManiacDC,

Glad to see you're back :)

I haven't added this to my fork yet, but been testing this out and seems to help with performance of my changes:

Added the following to the end of the function CleanupWordList()

;Zap all lastused values greater than a threshold to reduce dataset size for lastused functionality g_WordListDB.Query("UPDATE words SET lastused = 0 where lastused < date('now') and lastused <> 0;")

Since I'm only interested in recently used words that were used today, zapping the database of any previous stuff keeps the set smaller to work with. Obviously if people never restart the application, this is of no help to them.

Cheers!

ManiacDC commented 9 years ago

Thanks! Seems useful... I'd probably parameterize it so that it removes words that haven't been typed in X days.

Also related to: https://github.com/ManiacDC/TypingAid/issues/24

Theclaws commented 9 years ago

Figured you would parameterize it :) If you add a feature to address #24, that means that the zap I just suggested in CleanupWordlist would have to be conditional, based on if the feature #24 is enabled/not.

Theclaws commented 8 years ago

Hi @ManiacDC. Put together a pull request 67 (https://github.com/ManiacDC/TypingAid/pull/67) to illustrate a slightly more mature version of this concept that I've been personally using for a while now.

Fits my needs - thought I would share to see if you build on it / polish it to your standards should you consider implementing this feature.