This is the new home of the egghelp.org community forum.
All data has been migrated (including user logins/passwords) to a new phpBB version.


For more information, see this announcement post. Click the X in the top right-corner of this box to dismiss this message.

Need a !learn Script with wildcard search

Requests for complete scripts or modifications/fixes for scripts you didn't write. Response not guaranteed, and no thread bumping!
Post Reply
s
shixxor
Voice
Posts: 4
Joined: Fri Feb 26, 2010 5:40 pm

Need a !learn Script with wildcard search

Post by shixxor »

Hi community,

I have had a look at all of the dictionary/learn/info scripts but I didnt found one that fits my special need.

I want an info script that helps ppl out as they call i.e. "!info test" then it posts its definition.... nothing special here but:

i need this to output the word even if its not typed completely like for example i add the word "minority report" and now i need the script to post the whole description of "minority report" when users just type "!info minor" or "!info mino"

i must also be able to put spaces into the keywords to learn like: !learn add "minority report" "A movie by steven spielberg"

It would we very very cool if u could recommend me a script that does that or if u could tell me how to modify an existing one...

Thank you very much in advance!

greetz,
Stefan
User avatar
arfer
Master
Posts: 436
Joined: Fri Nov 26, 2004 8:45 pm
Location: Manchester, UK

Post by arfer »

The following script should do the trick from what limited amount of testing I've done.

I do not feel it is suitable for a very large database of definitions due to the search methods employed. For one thing I would have preferred to use lsearch for a case insensitive seach of the existing records rather than iterating through them and using string match (-nocase option is not available for lsearch with Tcl versions before 8.5, which still applies to many bot installations).

In any case, a better, more comprehensive script would use a database engine such as mysql.

To use the script below, the output channel must permit text formatting such as colors.

Code: Select all

# learn.tcl

# to add a fact and definition in learn.txt
# you must use -> shown in the syntax below to seperate the fact from the definition
# !learn fact -> definition

# to recall the definition for fact
# firstly tries an exact match then the smallest partial match beginning with fact
# !recall fact

# to remove any record exactly matching fact from learn.txt
# !unlearn fact

bind PUB - !learn pLearnLearn
bind PUB - !recall pLearnRecall
bind PUB - !unlearn pLearnUnlearn

proc pLearnError {number nick chan {arg1 ""}} {
    set prefix (\00304$nick\003)
    switch -- $number {
        01 {set output "Incorrect syntax, use \00312!learn fact -> definition\003"}
        02 {set output "A definition already exists \00312$arg1\003"}
        03 {set output "Nothing found for \00312$arg1\003"}
        04 {set output "The characters \00312->\003 can only be used once to seperate the fact from the definition"}
        default {}
    }
    putserv "PRIVMSG $chan :$prefix $output"
    return 0
}

proc pLearnLearn {nick uhost hand chan text} {
    global vLearnData
    set record [regsub -all -- {[\s]{2,}} [string trim $text] { }]
    if {[regexp -- {^(.+) -> } $record -> fact]} {
        if {[regexp -all -- {->} $record] == 1} {
            pLearnRead
            if {[set found [pLearnSearchFull $fact]] == 0} {
                pLearnWrite $record
                pLearnOutput 01 $nick $chan $record
            } else {pLearnError 02 $nick $chan [lindex $found 1]}
            unset -nocomplain -- vLearnData
        } else {pLearnError 04 $nick $chan}
    } else {pLearnError 01 $nick $chan}
    return 0
}

proc pLearnOutput {number nick chan {arg1 ""}} {
    set prefix (\00303$nick\003)
    switch -- $number {
        01 {set output "Learnt \00312$arg1\003"}
        02 {set output "Found full match \00312$arg1\003"}
        03 {set output "Found partial match \00312$arg1\003"}
        04 {set output "Unlearnt \00312$arg1\003"}
        default {}
    }
    putserv "PRIVMSG $chan :$prefix $output"
    return 0
}

proc pLearnRead {} {
    global vLearnData
    if {[file exists learn.txt]} {
        set fp [open learn.txt r]
        set vLearnData [split [read -nonewline $fp] \n]
        close $fp
    }
    return 0
}

proc pLearnRecall {nick uhost hand chan text} {
    global vLearnData
    set fact [regsub -all -- {[\s]{2,}} [string trim $text] { }]
    pLearnRead
    if {[set result [pLearnSearchFull $fact]] != 0} {
        pLearnOutput 02 $nick $chan [lindex $result 1]
    } elseif {[set result [pLearnSearchPartial $fact]] != 0} {
        pLearnOutput 03 $nick $chan $result
    } else {
        pLearnError 03 $nick $chan $fact
    }
    unset -nocomplain -- vLearnData
    return 0
}

proc pLearnSearchFull {fact} {
    global vLearnData
    if {([info exists vLearnData]) && ([llength $vLearnData] > 0)} {
        for {set position 0} {$position < [llength $vLearnData]} {incr position} {
            if {[string match -nocase "$fact -> *" [lindex $vLearnData $position]]} {
                set found [list $position [lindex $vLearnData $position]]
                break
            }
        }
    }
    if {[info exists found]} {return $found} else {return 0}
}

proc pLearnSearchPartial {fact} {
    global vLearnData
    if {([info exists vLearnData]) && ([llength $vLearnData] > 0)} {
        set vLearnData [lsort -increasing $vLearnData]
        foreach record $vLearnData {
            if {[string match -nocase "$fact* -> *" $record]} {
                set found $record
                break
            }
        }
    }
    if {[info exists found]} {return $found} else {return 0}
}

proc pLearnUnlearn {nick uhost hand chan text} {
    global vLearnData
    set fact [regsub -all -- {[\s]{2,}} [string trim $text] { }]
    pLearnRead
    if {[set found [pLearnSearchFull $fact]] != 0} {
        set vLearnData [lreplace $vLearnData [lindex $found 0] [lindex $found 0]] 
        set fp [open learn.txt w]
        if {[llength $vLearnData] != 0} {
            puts $fp [join $vLearnData \n]
        }
        close $fp
        pLearnOutput 04 $nick $chan [lindex $found 1]
    } else {pLearnError 03 $nick $chan $fact}
    unset -nocomplain -- vLearnData
    return 0
}

proc pLearnWrite {record} {
    set fp [open learn.txt a]
    puts $fp $record
    close $fp
    return 0
}

putlog "learn.tcl loaded"

# eof
** Edit** slight modification to code 01/03/10 6:15 GMT, to ensure that a space is needed either side of the -> characters in items to learn
Last edited by arfer on Mon Mar 01, 2010 2:15 am, edited 1 time in total.
I must have had nothing to do
s
shixxor
Voice
Posts: 4
Joined: Fri Feb 26, 2010 5:40 pm

Post by shixxor »

YEAH thx!!! ill try it out...
User avatar
arfer
Master
Posts: 436
Joined: Fri Nov 26, 2004 8:45 pm
Location: Manchester, UK

Post by arfer »

Modification to the above script (adding !facts command) plus some examples on how to use the script

Code: Select all

# learn.tcl

# to add a fact and definition in learn.txt
# you must use -> shown in the syntax below to seperate the fact from the definition
# !learn fact -> definition

# to recall the definition for fact
# firstly tries an exact match then the smallest partial match beginning with fact
# !recall fact

# to remove any record exactly matching fact from learn.txt
# !unlearn fact

bind PUB - !facts pLearnFacts
bind PUB - !learn pLearnLearn
bind PUB - !recall pLearnRecall
bind PUB - !unlearn pLearnUnlearn

set vLearnVersion 2.0

proc pLearnError {number nick chan {arg1 ""}} {
    set prefix (\00304$nick\003)
    switch -- $number {
        01 {set output "Incorrect syntax, use \00312!learn fact -> definition\003"}
        02 {set output "A definition already exists \00312$arg1\003"}
        03 {set output "Nothing found for \00312$arg1\003"}
        04 {set output "The characters \00312->\003 can only be used once to seperate the fact from the definition"}
        05 {set output "Incorrect syntax, use \00312!facts\003 without additional arguments"}
        06 {set output "No facts currently in the database"}
        default {}
    }
    putserv "PRIVMSG $chan :$prefix $output"
    return 0
}

proc pLearnFacts {nick uhost hand chan text} {
    global vLearnData
    if {[llength [split [string trim $text]]] == 0} {
        pLearnRead
        if {([info exists vLearnData]) && ([llength $vLearnData] > 0)} {
            pLearnOutput 05 $nick $chan [llength $vLearnData]
        } else {pLearnError 06 $nick $chan}
        unset -nocomplain -- vLearnData
    } else {pLearnError 05 $nick $chan}
    return 0
}

proc pLearnLearn {nick uhost hand chan text} {
    global vLearnData
    set record [regsub -all -- {[\s]{2,}} [string trim $text] { }]
    if {[regexp -- {^(.+) -> } $record -> fact]} {
        if {[regexp -all -- {->} $record] == 1} {
            pLearnRead
            if {[set found [pLearnSearchFull $fact]] == 0} {
                pLearnWrite $record
                pLearnOutput 01 $nick $chan $record
            } else {pLearnError 02 $nick $chan [lindex $found 1]}
            unset -nocomplain -- vLearnData
        } else {pLearnError 04 $nick $chan}
    } else {pLearnError 01 $nick $chan}
    return 0
}

proc pLearnOutput {number nick chan {arg1 ""}} {
    set prefix (\00303$nick\003)
    switch -- $number {
        01 {set output "Learnt \00312$arg1\003"}
        02 {set output "Found full match \00312$arg1\003"}
        03 {set output "Found partial match \00312$arg1\003"}
        04 {set output "Unlearnt \00312$arg1\003"}
        05 {set output "Current database size \00312$arg1\003 fact(s)"}
        default {}
    }
    putserv "PRIVMSG $chan :$prefix $output"
    return 0
}

proc pLearnRead {} {
    global vLearnData
    if {[file exists learn.txt]} {
        set fp [open learn.txt r]
        set vLearnData [split [read -nonewline $fp] \n]
        close $fp
    }
    return 0
}

proc pLearnRecall {nick uhost hand chan text} {
    global vLearnData
    set fact [regsub -all -- {[\s]{2,}} [string trim $text] { }]
    pLearnRead
    if {[set result [pLearnSearchFull $fact]] != 0} {
        pLearnOutput 02 $nick $chan [lindex $result 1]
    } elseif {[set result [pLearnSearchPartial $fact]] != 0} {
        pLearnOutput 03 $nick $chan $result
    } else {
        pLearnError 03 $nick $chan $fact
    }
    unset -nocomplain -- vLearnData
    return 0
}

proc pLearnSearchFull {fact} {
    global vLearnData
    if {([info exists vLearnData]) && ([llength $vLearnData] > 0)} {
        for {set position 0} {$position < [llength $vLearnData]} {incr position} {
            if {[string match -nocase "$fact -> *" [lindex $vLearnData $position]]} {
                set found [list $position [lindex $vLearnData $position]]
                break
            }
        }
    }
    if {[info exists found]} {return $found} else {return 0}
}

proc pLearnSearchPartial {fact} {
    global vLearnData
    if {([info exists vLearnData]) && ([llength $vLearnData] > 0)} {
        set vLearnData [lsort -increasing $vLearnData]
        foreach record $vLearnData {
            if {[string match -nocase "$fact* -> *" $record]} {
                set found $record
                break
            }
        }
    }
    if {[info exists found]} {return $found} else {return 0}
}

proc pLearnUnlearn {nick uhost hand chan text} {
    global vLearnData
    set fact [regsub -all -- {[\s]{2,}} [string trim $text] { }]
    pLearnRead
    if {[set found [pLearnSearchFull $fact]] != 0} {
        set vLearnData [lreplace $vLearnData [lindex $found 0] [lindex $found 0]] 
        set fp [open learn.txt w]
        if {[llength $vLearnData] != 0} {
            puts $fp [join $vLearnData \n]
        }
        close $fp
        pLearnOutput 04 $nick $chan [lindex $found 1]
    } else {pLearnError 03 $nick $chan $fact}
    unset -nocomplain -- vLearnData
    return 0
}

proc pLearnWrite {record} {
    set fp [open learn.txt a]
    puts $fp $record
    close $fp
    return 0
}

putlog "learn.tcl version $vLearnVersion loaded"

# eof

The command !facts will output the currect database size

<@arfer> !facts
<@osmosis> (arfer) No facts currently in the database

The command !facts is used without additional arguments

<@arfer> !facts 1
<@osmosis> (arfer) Incorrect syntax, use !facts without additional arguments


The command !learn fact -> definition will add a fact (and its definition) to the database

<@arfer> !learn The Usual Suspects -> A film with Kevin Spacey and Jeff Bridges
<@osmosis> (arfer) Learnt The Usual Suspects -> A film with Kevin Spacey and Jeff Bridges

<@arfer> !facts
<@osmosis> (arfer) Current database size 1 fact(s)


The same exact fact cannot be duplicated in the database, even with a different definition

<@arfer> !learn The Usual Suspects -> whatever
<@osmosis> (arfer) A definition already exists The Usual Suspects -> A film with Kevin Spacey and Jeff Bridges


The above is true irrepective of the case

<@arfer> !learn THE uSUal SUSPECts -> whatever
<@osmosis> (arfer) A definition already exists The Usual Suspects -> A film with Kevin Spacey and Jeff Bridges


Inexact facts, even with the same definition, would not be considered duplicates

<@arfer> !learn Usual Suspects -> A film with Kevin Spacey and Jeff Bridges
<@osmosis> (arfer) Learnt Usual Suspects -> A film with Kevin Spacey and Jeff Bridges

<@arfer> !facts
<@osmosis> (arfer) Current database size 2 fact(s)


The command !learn fact -> definition must be used exactly as shown, with the characters " -> " seperating the fact from the definition

<@arfer> !learn K-PAX-> A film with Kevin Spacey
<@osmosis> (arfer) Incorrect syntax, use !learn fact -> definition

<@arfer> !learn K-PAX ->A film with Kevin Spacey
<@osmosis> (arfer) Incorrect syntax, use !learn fact -> definition

<@arfer> !learn K-PAX, A film with Kevin Spacey
<@osmosis> (arfer) Incorrect syntax, use !learn fact -> definition

<@arfer> !learn K-PAX -> A film with Kevin Spacey
<@osmosis> (arfer) Learnt K-PAX -> A film with Kevin Spacey

<@arfer> !facts
<@osmosis> (arfer) Current database size 3 fact(s)


The characters -> cannot be used elsewhere in the !learn command, within the fact or definition

<@arfer> !learn Elephant -> A large mammal -> African or Asian varieties exist
<@osmosis> (arfer) The characters -> can only be used once to seperate the fact from the definition


The command !unlearn fact is used to remove the fact exactly, irrespective of case

<@arfer> !unlearn usuaL
<@osmosis> (arfer) Nothing found for usuaL

<@arfer> !unlearn usuaL suspects
<@osmosis> (arfer) Unlearnt Usual Suspects -> A film with Kevin Spacey and Jeff Bridges

<@arfer> !facts
<@osmosis> (arfer) Current database size 2 fact(s)


The command !recall fact will look for an exact match, irrerspective of case, or if not found the smallest partial match beginning with fact

<@arfer> !recall k-PAx
<@osmosis> (arfer) Found full match K-PAX -> A film with Kevin Spacey

<@arfer> !recall k
<@osmosis> (arfer) Found partial match K-PAX -> A film with Kevin Spacey


The command !recall fact will not find anything smaller than the specified fact

<@arfer> !recall k-PAx film
<@osmosis> (arfer) Nothing found for k-PAx film
I must have had nothing to do
Post Reply