first
commit
198b5dc62b
@ -0,0 +1,68 @@
|
||||
import socket, select, string, sys
|
||||
|
||||
username = raw_input("Enter a username: ") # type: str
|
||||
|
||||
def prompt() :
|
||||
sys.stdout.write('[' + username + '] ');
|
||||
sys.stdout.flush()
|
||||
|
||||
#main function
|
||||
if __name__ == "__main__":
|
||||
|
||||
if(len(sys.argv) < 3) :
|
||||
print 'Usage: python telnet.py hostname port'
|
||||
sys.exit()
|
||||
|
||||
host = sys.argv[1]
|
||||
port = int(sys.argv[2])
|
||||
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s.settimeout(2)
|
||||
|
||||
# connect to remote host
|
||||
try :
|
||||
s.connect((host, port))
|
||||
except :
|
||||
print 'Unable to connect'
|
||||
sys.exit()
|
||||
|
||||
print """
|
||||
/$$ /$$ /$$$$$$$ /$$ /$$ /$$$$$$$ /$$ /$$
|
||||
| $$ / $$| $$__ $$| $$ | $$| $$__ $$ | $$ | $$
|
||||
| $$/ $$/| $$ \ $$| $$ | $$| $$ \ $$ /$$$$$$$| $$$$$$$ /$$$$$$ /$$$$$$
|
||||
\ $$$$/ | $$$$$$$/| $$ | $$| $$$$$$$ /$$_____/| $$__ $$ |____ $$|_ $$_/
|
||||
>$$ $$ | $$____/ | $$ | $$| $$__ $$ | $$ | $$ \ $$ /$$$$$$$ | $$
|
||||
/$$/\ $$| $$ | $$ | $$| $$ \ $$ | $$ | $$ | $$ /$$__ $$ | $$ /$$
|
||||
| $$ \ $$| $$ | $$$$$$/| $$$$$$$/ | $$$$$$$| $$ | $$| $$$$$$$ | $$$$/
|
||||
|__/ |__/|__/ \______/ |_______/ \_______/|__/ |__/ \_______/ \___/
|
||||
|
||||
|
||||
"""
|
||||
print 'Connected to remote host. Start sending messages'
|
||||
prompt()
|
||||
|
||||
s.send(username);
|
||||
|
||||
while 1:
|
||||
socket_list = [sys.stdin, s]
|
||||
|
||||
# Get the list sockets which are readable
|
||||
read_sockets, write_sockets, error_sockets = select.select(socket_list , [], [])
|
||||
|
||||
for sock in read_sockets:
|
||||
#incoming message from remote server
|
||||
if sock == s:
|
||||
data = sock.recv(4096)
|
||||
if not data :
|
||||
print '\nDisconnected from chat server'
|
||||
sys.exit()
|
||||
else :
|
||||
#print data
|
||||
sys.stdout.write(data)
|
||||
prompt()
|
||||
|
||||
#user entered a message
|
||||
else :
|
||||
msg = sys.stdin.readline()
|
||||
s.send(msg)
|
||||
prompt()
|
@ -0,0 +1,84 @@
|
||||
import socket, select
|
||||
|
||||
#Function to broadcast chat messages to all connected clients
|
||||
def broadcast (server_socket, sock, message):
|
||||
for socket in CONNECTION_LIST:
|
||||
if socket != server_socket and socket != sock : #Do not send the message to master socket and the client who has send us the message
|
||||
try :
|
||||
socket.send(message)
|
||||
except :
|
||||
# broken socket connection may be, chat client pressed ctrl+c for example
|
||||
socket.close()
|
||||
CONNECTION_LIST.remove(socket)
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
# List to keep track of socket descriptors
|
||||
CONNECTION_LIST = []
|
||||
RECV_BUFFER = 4096 # Advisable to keep it as an exponent of 2
|
||||
PORT = 5000 # you can change the port if you want
|
||||
USERNAMES = {} #new data structure
|
||||
|
||||
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
# this has no effect, why ?
|
||||
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
server_socket.bind(("0.0.0.0", PORT))
|
||||
server_socket.listen(10)
|
||||
|
||||
# Add server socket to the list of readable connections
|
||||
CONNECTION_LIST.append(server_socket)
|
||||
|
||||
print "Your chat server started on port " + str(PORT)
|
||||
print """
|
||||
/$$
|
||||
|__/
|
||||
/$$$$$$$ /$$$$$$ /$$$$$$ /$$ /$$ /$$ /$$$$$$$ /$$$$$$
|
||||
/$$_____/ /$$__ $$ /$$__ $$| $$ /$$/| $$| $$__ $$ /$$__ $$
|
||||
| $$$$$$ | $$$$$$$$| $$ \__/ \ $$/$$/ | $$| $$ \ $$| $$ \ $$
|
||||
\____ $$| $$_____/| $$ \ $$$/ | $$| $$ | $$| $$ | $$
|
||||
/$$$$$$$/| $$$$$$$| $$ \ $/ | $$| $$ | $$| $$$$$$$
|
||||
|_______/ \_______/|__/ \_/ |__/|__/ |__/ \____ $$
|
||||
/$$ \ $$
|
||||
| $$$$$$/
|
||||
\______/
|
||||
"""
|
||||
|
||||
while 1:
|
||||
# Get the list sockets which are ready to be read through select
|
||||
read_sockets,write_sockets,error_sockets = select.select(CONNECTION_LIST,[],[])
|
||||
|
||||
for sock in read_sockets:
|
||||
#New connection
|
||||
if sock == server_socket:
|
||||
# Handle the case in which there is a new connection recieved through server_socket
|
||||
sockfd, addr = server_socket.accept()
|
||||
CONNECTION_LIST.append(sockfd)
|
||||
username = sockfd.recv(1024)
|
||||
print "Client (%s, %s) connected" % addr
|
||||
# add a key - value pair to be able to map a connection to a username
|
||||
USERNAMES[sockfd.getpeername()] = username
|
||||
broadcast(server_socket, sockfd, "%s entered the room\n" % username)
|
||||
|
||||
|
||||
#Some incoming message from a client
|
||||
else:
|
||||
# Data recieved from client, process it
|
||||
try:
|
||||
#In Windows, sometimes when a TCP program closes abruptly,
|
||||
# a "Connection reset by peer" exception will be thrown
|
||||
data = sock.recv(RECV_BUFFER)
|
||||
if data:
|
||||
broadcast(server_socket, sock, "\r" + '[' + str(USERNAMES[sock.getpeername()]) + '] ' + data) #use the data structure previously defined to send the correct usernames
|
||||
else:
|
||||
# remove the socket that's broken
|
||||
if sock in SOCKET_LIST:
|
||||
SOCKET_LIST.remove(sock)
|
||||
|
||||
except:
|
||||
broadcast(server_socket, sock, "Client (%s, %s) is offline\n" % addr)
|
||||
print "Client (%s, %s) is offline" % addr
|
||||
sock.close()
|
||||
CONNECTION_LIST.remove(sock)
|
||||
continue
|
||||
|
||||
server_socket.close()
|
@ -0,0 +1,24 @@
|
||||
#this script is from the server side, to listen.
|
||||
|
||||
import socket
|
||||
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
|
||||
s.bind(('localhost', 3333))
|
||||
|
||||
s.listen(5)
|
||||
flag = 0
|
||||
while True:
|
||||
connect, addr = s.accept()
|
||||
print("Connection Address:" + str(addr))
|
||||
|
||||
str_return = "I am listening. Waiting for command."
|
||||
connect.sendto(bytes(str_return, 'utf-8'), addr)
|
||||
|
||||
str_recv, temp = connect.recvfrom(1024)
|
||||
print(str_recv)
|
||||
|
||||
str_return = "I got your command, it is " + str(str_recv)
|
||||
connect.sendto(bytes(str_return, 'utf-8'), addr)
|
||||
|
||||
connect.close()
|
@ -0,0 +1,20 @@
|
||||
#this script is for the client side
|
||||
|
||||
import socket
|
||||
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
|
||||
s.connect(("localhost", 3333))
|
||||
|
||||
str_recv = s.recv(1024)
|
||||
|
||||
print(str(str_recv))
|
||||
|
||||
str_send = "I am here!"
|
||||
|
||||
s.send(bytes(str_send, 'utf-8'))
|
||||
|
||||
str_recv = s.recv(1024)
|
||||
|
||||
print(str(str_recv))
|
||||
s.close()
|
Binary file not shown.
After Width: | Height: | Size: 1.1 MiB |
Binary file not shown.
After Width: | Height: | Size: 29 KiB |
Binary file not shown.
After Width: | Height: | Size: 132 KiB |
@ -0,0 +1,94 @@
|
||||
{
|
||||
"pre": [
|
||||
"dont don't",
|
||||
"cant can't",
|
||||
"wont won't",
|
||||
"recollect remember",
|
||||
"dreamt dreamed",
|
||||
"dreams dream",
|
||||
"maybe perhaps",
|
||||
"how what",
|
||||
"when what",
|
||||
"certainly yes",
|
||||
"machine computer",
|
||||
"computers computer",
|
||||
"were was",
|
||||
"you're you are",
|
||||
"i'm i am",
|
||||
"same alike"
|
||||
],
|
||||
"post": [
|
||||
"am are",
|
||||
"your my",
|
||||
"me you",
|
||||
"myself yourself",
|
||||
"yourself myself",
|
||||
"i you",
|
||||
"you I",
|
||||
"my your",
|
||||
"i'm you are"
|
||||
],
|
||||
"synon": [
|
||||
"belief feel think believe wish",
|
||||
"sad unhappy depressed sick",
|
||||
"sorry apologise"
|
||||
],
|
||||
"quit": [],
|
||||
"keywords": [
|
||||
{
|
||||
"token": "xnone",
|
||||
"weight": 0,
|
||||
"rules": [
|
||||
{
|
||||
"decomp": "*",
|
||||
"reasmb": [
|
||||
"You won't believe (1) *scandal*",
|
||||
"(1) IT\u2019S OFFICIAL.",
|
||||
"(1) WEIRD!!!!"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"token": "?",
|
||||
"weight": 0,
|
||||
"rules": [
|
||||
{
|
||||
"decomp": "* ?",
|
||||
"reasmb": [
|
||||
"(1) ????????? SHOCKED!",
|
||||
"(1) ????????? (DRASTIC)",
|
||||
"(1) ????????? (no clickbait)"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"token": "sorry",
|
||||
"weight": 0,
|
||||
"rules": [
|
||||
{
|
||||
"decomp": "*",
|
||||
"reasmb": [
|
||||
"You won't believe who is sorry! *EMOTIONAL*",
|
||||
"He apologised! *EMOTIONAL*"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"token": "dreamed",
|
||||
"weight": 0,
|
||||
"rules": [
|
||||
{
|
||||
"decomp": "*",
|
||||
"reasmb": [
|
||||
"MY CRAZY DREAMS!!!! You won\u2019t believe this."
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"initial": "Tell me your post title.",
|
||||
"final": "Goodluck. Go get coins."
|
||||
}
|
@ -0,0 +1,202 @@
|
||||
/*
|
||||
Michael Murtaugh
|
||||
Following Charles Hayden's 1990's interpretation implemented in Java
|
||||
(C) 2018 and released under the Free Art License 1.3
|
||||
See LICENSE.txt and http://artlibre.org/licence/lal/en/
|
||||
|
||||
Use the accompanying eliza_script_to_json.py to prepare the rules in JSON format
|
||||
|
||||
*/
|
||||
function chatbot (rules, debug) {
|
||||
var saved_statements = [];
|
||||
|
||||
function process_rules (rules) {
|
||||
// transfrom / pre-process the rules
|
||||
function looping_iterator (l) {
|
||||
var next = function () {
|
||||
var ret = l[next.i];
|
||||
if (++next.i >= l.length) { next.i = 0 };
|
||||
return ret;
|
||||
};
|
||||
next.length = l.length;
|
||||
next.i = 0;
|
||||
next.items = l;
|
||||
return next;
|
||||
}
|
||||
// index pre + post and tokenize results
|
||||
function _index (name) {
|
||||
var new_value = {};
|
||||
rules[name].forEach(function (x) {
|
||||
var words = tokenize(x),
|
||||
word = words.shift();
|
||||
new_value[word] = words;
|
||||
})
|
||||
rules[name] = new_value;
|
||||
}
|
||||
_index("pre");
|
||||
_index("post");
|
||||
// index synonmys by first word
|
||||
var new_synon = {};
|
||||
rules.synon.forEach(function (x) {
|
||||
var words = tokenize(x);
|
||||
new_synon[words[0]] = words;
|
||||
})
|
||||
rules.synon = new_synon;
|
||||
// index keywords by name
|
||||
rules.keywords_by_token = {};
|
||||
rules.keywords.forEach(function (x) {
|
||||
rules.keywords_by_token[x.token] = x;
|
||||
x.rules.forEach(function (r) {
|
||||
// ensure list
|
||||
if (!Array.isArray(r.reasmb)) { r.reasmb = [r.reasmb]; }
|
||||
// wrap the reasmb list in a looping iterator that perserves its state
|
||||
r.reasmb = looping_iterator(r.reasmb);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// function trim (text) { return text.replace(/\s+$/, "").replace(/\s+/, ""); }
|
||||
function trimword (text) {
|
||||
return text
|
||||
.replace(/[^a-zA-Zéèàöùç]+$/, "")
|
||||
.replace(/^[^a-zA-Zéèàöùç]+/, "");
|
||||
}
|
||||
|
||||
function tokenize (text) {
|
||||
return (trimword(text).split(/\s+/).map(trimword));
|
||||
}
|
||||
|
||||
// used for both pre + post subs
|
||||
function sub (tokens, subst) {
|
||||
for (var i=0, l=tokens.length; i<l; i++) {
|
||||
var sub = subst[tokens[i].toLowerCase()];
|
||||
if (sub) {
|
||||
if (Array.isArray(sub)) {
|
||||
Array.prototype.splice.apply(tokens, [i, 1].concat(sub));
|
||||
i += (sub.length - 1);
|
||||
} else {
|
||||
tokens[i] = sub;
|
||||
}
|
||||
}
|
||||
}
|
||||
return tokens;
|
||||
}
|
||||
|
||||
function select_keywords (tokens) {
|
||||
var ret = [];
|
||||
for (var i=0, l=tokens.length; i<l; i++) {
|
||||
var w = tokens[i].toLowerCase(),
|
||||
rule = rules.keywords_by_token[w];
|
||||
if (rule) { ret.push(rule); }
|
||||
}
|
||||
if (rules.keywords_by_token.xnone && rules.keywords_by_token.xnone.weight != 0) {
|
||||
// append xnone rule pre-sort
|
||||
ret.push(rules.keywords_by_token.xnone);
|
||||
}
|
||||
ret.sort(function (a, b) { return b.weight - a.weight });
|
||||
if (rules.keywords_by_token.xnone && rules.keywords_by_token.xnone.weight == 0) {
|
||||
// append xnone rule post-sort (ensuring it's last)
|
||||
ret.push(rules.keywords_by_token.xnone);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
function compile_pattern (pattern) {
|
||||
// compile a decomposition pattern
|
||||
// * i @cannot * ==> i(cannot|cant|...)(.+)
|
||||
// * i* @belief *you * ==> (belief|feel|think|believe|wish)
|
||||
// * i @belief i *
|
||||
var ret = pattern
|
||||
.replace(/ *\* */g, "*") // compact spaces around stars
|
||||
.replace(/\*/g, "(.*?)")
|
||||
.replace(/@(\w+)/, function (match, word) {
|
||||
var syn = rules.synon[word.toLowerCase()];
|
||||
if (syn) {
|
||||
return "("+syn.join("|")+")";
|
||||
} else {
|
||||
console.log("Missing @synonym", word);
|
||||
return match;
|
||||
}
|
||||
});
|
||||
return "^"+ret+"$";
|
||||
}
|
||||
|
||||
function match_decomp (pattern, tokens) {
|
||||
var ppat = compile_pattern(pattern);
|
||||
if (debug) {
|
||||
console.log("compile_pattern.in", pattern);
|
||||
console.log("compile_pattern.out", ppat);
|
||||
}
|
||||
var ppat = new RegExp(ppat, "i");
|
||||
return ppat.exec(tokens.join(" "));
|
||||
}
|
||||
|
||||
function do_post (txt) {
|
||||
var tokens = tokenize(txt);
|
||||
tokens = sub(tokens, rules.post);
|
||||
return tokens.join(" ");
|
||||
}
|
||||
|
||||
function do_reasmb (reasmb, match, tokens) {
|
||||
if (Array.isArray(match)) {
|
||||
return reasmb.replace(/\((\d+)\)/, function (m, n) {
|
||||
return do_post(match[parseInt(n)]); // apply POST substitutions here to matching input
|
||||
});
|
||||
} else {
|
||||
return reasmb;
|
||||
}
|
||||
}
|
||||
|
||||
function apply_keywords (keywords, tokens) {
|
||||
for (var i=0, l=keywords.length; i<l; i++) {
|
||||
var keyword = keywords[i];
|
||||
if ((keyword.token == "xnone") && (saved_statements.length > 0)) {
|
||||
if (debug) { console.log("using saved statement"); }
|
||||
return saved_statements.shift();
|
||||
}
|
||||
var loop = true;
|
||||
while (loop) {
|
||||
loop = false;
|
||||
if (debug) { console.log("trying keyword", keyword.token); }
|
||||
for (var ri=0, rl = keyword.rules.length; ri<rl; ri++) {
|
||||
var rule = keyword.rules[ri];
|
||||
if (debug) { console.log("trying rule", rule.decomp, "("+(ri+1)+"/"+rl+")"); }
|
||||
var match = match_decomp(rule.decomp, tokens);
|
||||
if (match) {
|
||||
var ra = rule.reasmb();
|
||||
if (rule['save']) {
|
||||
var save = do_reasmb(ra, match, tokens);
|
||||
if (debug) { console.log("save", save); }
|
||||
saved_statements.push(save);
|
||||
} else if (ra.indexOf("goto ") == 0) {
|
||||
var goto_name = ra.substr(5);
|
||||
if (debug) { console.log("goto", goto_name); }
|
||||
keyword = rules.keywords_by_token[goto_name];
|
||||
loop = true;
|
||||
break;
|
||||
} else {
|
||||
if (debug) { console.log("match", match, ra); }
|
||||
return do_reasmb(ra, match, tokens);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function process (text) {
|
||||
if (debug) { console.log("input", text); }
|
||||
var tokens = tokenize(text);
|
||||
if (debug) { console.log("tokens", tokens); }
|
||||
tokens = sub(tokens, rules.pre);
|
||||
if (debug) { console.log("pre", tokens); }
|
||||
var keywords = select_keywords(tokens);
|
||||
if (debug) { console.log("keywords", keywords.map(function (x) { return x.token })); }
|
||||
var output = apply_keywords(keywords, tokens);
|
||||
if (debug) { console.log("output", output); }
|
||||
return output;
|
||||
}
|
||||
|
||||
process_rules(rules);
|
||||
return process;
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>CLICKBAIT GENERATOR</title>
|
||||
<meta charset="utf-8">
|
||||
<style type="text/css">
|
||||
* {
|
||||
font-family: sans-serif;
|
||||
font-size: calc(1vw + 3vh);
|
||||
}
|
||||
#wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: absolute;
|
||||
left: 5%; top: 5%; right: 5%; bottom: 5%;
|
||||
}
|
||||
#textinput {
|
||||
width: 100%;
|
||||
border: none;
|
||||
background: none;
|
||||
}
|
||||
#input {
|
||||
padding: 2%;
|
||||
flex: 0 1 auto;
|
||||
background: red;
|
||||
}
|
||||
#display {
|
||||
flex: 1 1 auto;
|
||||
background: lightgrey;
|
||||
padding: 2%;
|
||||
overflow: auto;
|
||||
}
|
||||
#display div.msg {
|
||||
padding-bottom: 0.5em;
|
||||
color: grey;
|
||||
}
|
||||
#display div.human {
|
||||
color: black;
|
||||
}
|
||||
#display div.bot {
|
||||
color: black;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
#display div.debug {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="wrapper">
|
||||
<div id="display">
|
||||
</div>
|
||||
<div id="input">
|
||||
<input type="text" id="textinput" autofocus />
|
||||
</div>
|
||||
</div>
|
||||
<script src="eliza.js"></script>
|
||||
<script>
|
||||
function eliza (rules) {
|
||||
var input = document.getElementById("textinput"),
|
||||
output = document.getElementById("display"),
|
||||
bot = chatbot(rules, true);
|
||||
|
||||
function log (msg, kls) {
|
||||
var d = document.createElement("div");
|
||||
d.setAttribute("class", "msg " + kls);
|
||||
d.innerHTML = msg;
|
||||
display.appendChild(d);
|
||||
}
|
||||
|
||||
function say (msg) {
|
||||
log(msg, "bot");
|
||||
display.scrollTop = display.scrollTopMax;
|
||||
}
|
||||
|
||||
input.addEventListener("keypress", function (event) {
|
||||
if (event.keyCode == 13) {
|
||||
var text = input.value;
|
||||
log(text, "user");
|
||||
say(bot(text), "bot");
|
||||
input.value = "";
|
||||
input.focus();
|
||||
}
|
||||
});
|
||||
say(rules.initial);
|
||||
}
|
||||
</script>
|
||||
<script src="doctor.js"></script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,60 @@
|
||||
"""
|
||||
Michael Murtaugh
|
||||
Following Charles Hayden's 1990's interpretation implemented in Java
|
||||
(C) 2018 and released under the Free Art License 1.3
|
||||
See LICENSE.txt and http://artlibre.org/licence/lal/en/
|
||||
|
||||
For use with eliza.js
|
||||
Usage:
|
||||
|
||||
python3 eliza_script_to_json.py < doctor.txt > doctor.json
|
||||
|
||||
"""
|
||||
import sys, json
|
||||
|
||||
output = {}
|
||||
output['pre'] = pre = []
|
||||
output['post'] = post = []
|
||||
output['synon'] = synon = []
|
||||
output['quit'] = quit = []
|
||||
output['keywords'] = keys = []
|
||||
for line in sys.stdin:
|
||||
line = line.strip()
|
||||
if line.startswith("#") or not line:
|
||||
continue
|
||||
cmd, rest = line.split(" ", 1)
|
||||
cmd = cmd.strip()
|
||||
rest = rest.strip()
|
||||
if cmd == "initial:":
|
||||
output['initial'] = rest
|
||||
elif cmd == "final:":
|
||||
output['final'] = rest
|
||||
elif cmd == "pre:":
|
||||
pre.append(rest)
|
||||
elif cmd == "post:":
|
||||
post.append(rest)
|
||||
elif cmd == "synon:":
|
||||
synon.append(rest)
|
||||
elif cmd == "key:":
|
||||
try:
|
||||
token, weight = rest.split()
|
||||
except ValueError:
|
||||
token = rest.strip()
|
||||
weight = 0
|
||||
print ("key", token, int(weight), file=sys.stderr)
|
||||
keys.append({"token": token.strip(), "weight": int(weight), "rules": []})
|
||||
elif line.startswith("decomp:"):
|
||||
_, pattern = line.split(" ", 1)
|
||||
pattern = pattern.strip()
|
||||
if pattern.startswith("$"):
|
||||
decomp = {"decomp": pattern[1:].strip(), "reasmb": [], "save": True}
|
||||
else:
|
||||
decomp = {"decomp": pattern, "reasmb": []}
|
||||
print ("decomp", decomp, file=sys.stderr)
|
||||
keys[-1]['rules'].append(decomp)
|
||||
elif line.startswith("reasmb:"):
|
||||
_, pattern = line.split(" ", 1)
|
||||
print ("reasmb", pattern, file=sys.stderr)
|
||||
keys[-1]['rules'][-1]['reasmb'].append(pattern.strip())
|
||||
|
||||
print (json.dumps(output, indent=2))
|
@ -0,0 +1,64 @@
|
||||
How Eliza Works
|
||||
|
||||
All the behavior of Eliza is controlled by a script file.
|
||||
The standard script is attached to the end of this explanation.
|
||||
|
||||
Eliza starts by reading the script file. Because of Java security, it
|
||||
must be on the same server as the class files. Eliza then reads a line at
|
||||
a time from the user, processes it, and formulates a reply.
|
||||
|
||||
Processing consists of the following steps.
|
||||
First the sentence broken down into words, separated by spaces. All further
|
||||
processing takes place on these words as a whole, not on the individual
|
||||
characters in them.
|
||||
Second, a set of pre-substitutions takes place.
|
||||
Third, Eliza takes all the words in the sentence and makes a list of all
|
||||
keywords it finds. It sorts this keyword list in descending weight. It
|
||||
process these keywords until it produces an output.
|
||||
Fourth, for the given keyword, a list of decomposition patterns is searched.
|
||||
The first one that matches is selected. If no match is found, the next keyword
|
||||
is selected instead.
|
||||
Fifth, for the matching decomposition pattern, a reassembly pattern is
|
||||
selected. There may be several reassembly patterns, but only one is used
|
||||
for a given sentence. If a subsequent sentence selects the same decomposition
|
||||
pattern, the next reassembly pattern in sequence is used, until they have all
|
||||
been used, at which point Eliza starts over with the first reassembly pattern.
|
||||
Sixth, a set of post-substitutions takes place.
|
||||
Finally, the resulting sentence is displayed as output.
|
||||
|
||||
The script is used to construct the pre and post substitution lists, the
|
||||
keyword lists, and the decomposition and reassembly patterns.
|
||||
In addition, there is a synonym matching facility, which is explained below.
|
||||
|
||||
Every line of script is prefaced by a tag that tells what list it is
|
||||
part of. Here is an explanation of the tags.
|
||||
|
||||
initial: Eliza says this when it starts.
|
||||
final: Eliza says this when it quits.
|
||||
quit: If the input is this, then Eliza quits. Any number permitted.
|
||||
pre: Part of the pre-substitution list. If the first word appears in
|
||||
the sentence, it is replaced by the rest of the words.
|
||||
post: Part of the post-subsititution list. If the first word appears
|
||||
in the sentence, it is replaced by the rest of the words.
|
||||
key: A keyword. Keywords with greater weight are selected in
|
||||
preference to ones with lesser weight.
|
||||
If no weight is given, it is assumed to be 1.
|
||||
decomp: A decomposition pattern. The character * stands for any
|
||||
sequence of words.
|
||||
reasmb: A reassembly pattern. A set of words matched by * in
|
||||
the decomposition pattern can be used as part of the reassembly.
|
||||
For instance, (2) inserts the words matched by the second *
|
||||
in the decomposition pattern.
|
||||
synon: A list of synonyms. In a decomposition rule, for instance, @be
|
||||
matches any of the words "be am is are was" because of the line:
|
||||
"synon: be am is are was". The match @be also counts as a *
|
||||
in numbering the matches for use by reassembly rules.
|
||||
|
||||
Other Special Rules
|
||||
If a $ appears first in a decomposition rule, then the output is formed as
|
||||
normal, but is saved and Eliza goes on to the next keyword. If no keywords
|
||||
match, and there are saved sentences, one of them is picked at random and
|
||||
used as the output, then it is discarded.
|
||||
If there are no saved sentences, and no keywords match, then it uses the
|
||||
keyword "xnone".
|
||||
|
@ -0,0 +1,13 @@
|
||||
from __future__ import print_function
|
||||
import json, sys, argparse
|
||||
|
||||
ap = argparse.ArgumentParser("wrap JSON in either a variable declaration (hardcode) or a callback (JSONP).")
|
||||
ap.add_argument("--variable", default="weft", help="define a variable")
|
||||
ap.add_argument("--callback", help="use a named callback (JSONP) -- overrides --variable")
|
||||
args = ap.parse_args()
|
||||
|
||||
d = json.load(sys.stdin)
|
||||
if args.callback:
|
||||
print ("{0}({1});".format(args.callback, json.dumps(d)))
|
||||
else:
|
||||
print ("{0} = {1};".format(args.variable, json.dumps(d)))
|
@ -0,0 +1,7 @@
|
||||
%.json: %.txt
|
||||
python3 eliza_script_to_json.py < $< > $@
|
||||
%.js: %.json
|
||||
python3 jsonp.py --callback "eliza" < $< > $@
|
||||
|
||||
doctor.html: doctor.json
|
||||
python3 json_to_print.py $< rules.template.html > $@
|
@ -0,0 +1,24 @@
|
||||
import collections
|
||||
|
||||
file = open("results.txt") # open and read file
|
||||
|
||||
trump_list = []
|
||||
|
||||
trump = set(line.strip() for line in open('trump.txt')) # words that are inside sad.txt
|
||||
|
||||
# in the future I should split words from punctuation, so Trump's count as Trump
|
||||
# for word in a.lower().split():
|
||||
|
||||
with open("results.txt") as f:
|
||||
for line in f:
|
||||
for word in line.split():
|
||||
if word in trump:
|
||||
#print(word + " this is sad")
|
||||
trump_list.append(line + "<br>")
|
||||
break
|
||||
|
||||
text_file = open("trump_news.htm", "w+")
|
||||
text_file.write("".join(trump_list))
|
||||
# print("".join(happy_list))
|
||||
# Close the file
|
||||
file.close()
|
@ -0,0 +1,20 @@
|
||||
from urllib.request import urlopen
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
html = urlopen('https://www.washingtonpost.com/')
|
||||
|
||||
bs = BeautifulSoup(html, "html.parser")
|
||||
|
||||
titles = bs.find_all('h2')
|
||||
titles_list = []
|
||||
|
||||
#getting the content of <a> tag inside h2
|
||||
for h2 in titles:
|
||||
titles_list.append(h2.a.text.strip())
|
||||
|
||||
# write() argument must be str, not list
|
||||
titles_list_strings = "\n".join(titles_list)
|
||||
|
||||
text_file = open("results.txt", "w")
|
||||
text_file.write(titles_list_strings)
|
||||
text_file.close()
|
@ -0,0 +1 @@
|
||||
Trump
|
@ -0,0 +1,48 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<title>Double tap</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="date" content="2019-09-25">
|
||||
<meta name="author" content="Rita Graca">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="icon" href="">
|
||||
<link rel="stylesheet" type="text/css" href="reset.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<script src="https://hammerjs.github.io/dist/hammer.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="myElement"></div>
|
||||
|
||||
</body>
|
||||
|
||||
<script>
|
||||
var myElement = document.getElementById('myElement');
|
||||
|
||||
// We create a manager object, which is the same as Hammer(), but without the presetted recognizers.
|
||||
var mc = new Hammer.Manager(myElement);
|
||||
|
||||
|
||||
// Tap recognizer with minimal 2 taps
|
||||
mc.add( new Hammer.Tap({ event: 'doubletap', taps: 2 }) );
|
||||
// Single tap recognizer
|
||||
mc.add( new Hammer.Tap({ event: 'singletap' }) );
|
||||
|
||||
|
||||
// we want to recognize this simulatenous, so a quadrupletap will be detected even while a tap has been recognized.
|
||||
mc.get('doubletap').recognizeWith('singletap');
|
||||
// we only want to trigger a tap, when we don't have detected a doubletap
|
||||
mc.get('singletap').requireFailure('doubletap');
|
||||
|
||||
|
||||
mc.on("doubletap", function(ev) {
|
||||
// myElement.textContent += ev.type +" ";
|
||||
var backColor = myElement.style.backgroundImage;
|
||||
myElement.style.backgroundImage = backColor === 'linear-gradient(pink, red)' ? "linear-gradient(red, pink)" : "linear-gradient(pink, red)";
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
</html>
|
@ -0,0 +1,48 @@
|
||||
/* http://meyerweb.com/eric/tools/css/reset/
|
||||
v2.0 | 20110126
|
||||
License: none (public domain)
|
||||
*/
|
||||
|
||||
html, body, div, span, applet, object, iframe,
|
||||
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
||||
a, abbr, acronym, address, big, cite, code,
|
||||
del, dfn, em, img, ins, kbd, q, s, samp,
|
||||
small, strike, strong, sub, sup, tt, var,
|
||||
b, u, i, center,
|
||||
dl, dt, dd, ol, ul, li,
|
||||
fieldset, form, label, legend,
|
||||
table, caption, tbody, tfoot, thead, tr, th, td,
|
||||
article, aside, canvas, details, embed,
|
||||
figure, figcaption, footer, header, hgroup,
|
||||
menu, nav, output, ruby, section, summary,
|
||||
time, mark, audio, video {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
font-size: 100%;
|
||||
font: inherit;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
/* HTML5 display-role reset for older browsers */
|
||||
article, aside, details, figcaption, figure,
|
||||
footer, header, hgroup, menu, nav, section {
|
||||
display: block;
|
||||
}
|
||||
body {
|
||||
line-height: 1;
|
||||
}
|
||||
ol, ul {
|
||||
list-style: none;
|
||||
}
|
||||
blockquote, q {
|
||||
quotes: none;
|
||||
}
|
||||
blockquote:before, blockquote:after,
|
||||
q:before, q:after {
|
||||
content: '';
|
||||
content: none;
|
||||
}
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
#myElement {
|
||||
background-image: linear-gradient(pink, red);
|
||||
height: 100vh;
|
||||
text-align: center;
|
||||
font: 30px/300px Arial, sans-serif;
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 182 KiB |
@ -0,0 +1,38 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<title>Pan up</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="icon" href="">
|
||||
<link rel="stylesheet" type="text/css" href="reset.css">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<script src="https://hammerjs.github.io/dist/hammer.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
|
||||
<div id="myElement"></div>
|
||||
|
||||
<script>
|
||||
var myElement = document.getElementById('myElement');
|
||||
|
||||
// create a simple instance
|
||||
// by default, it only adds horizontal recognizers
|
||||
var mc = new Hammer(myElement);
|
||||
|
||||
// let the pan gesture support all directions.
|
||||
// this will block the vertical scrolling on a touch-device while on the element
|
||||
mc.get('pan').set({ direction: Hammer.DIRECTION_ALL });
|
||||
|
||||
// listen to events...
|
||||
mc.on("panup", function(ev) {
|
||||
// myElement.textContent = ev.type +" gesture detected.";
|
||||
myElement.style.animation = "gradient 5s ease infinite";
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Binary file not shown.
After Width: | Height: | Size: 159 KiB |
@ -0,0 +1,48 @@
|
||||
/* http://meyerweb.com/eric/tools/css/reset/
|
||||
v2.0 | 20110126
|
||||
License: none (public domain)
|
||||
*/
|
||||
|
||||
html, body, div, span, applet, object, iframe,
|
||||
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
||||
a, abbr, acronym, address, big, cite, code,
|
||||
del, dfn, em, img, ins, kbd, q, s, samp,
|
||||
small, strike, strong, sub, sup, tt, var,
|
||||
b, u, i, center,
|
||||
dl, dt, dd, ol, ul, li,
|
||||
fieldset, form, label, legend,
|
||||
table, caption, tbody, tfoot, thead, tr, th, td,
|
||||
article, aside, canvas, details, embed,
|
||||
figure, figcaption, footer, header, hgroup,
|
||||
menu, nav, output, ruby, section, summary,
|
||||
time, mark, audio, video {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
font-size: 100%;
|
||||
font: inherit;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
/* HTML5 display-role reset for older browsers */
|
||||
article, aside, details, figcaption, figure,
|
||||
footer, header, hgroup, menu, nav, section {
|
||||
display: block;
|
||||
}
|
||||
body {
|
||||
line-height: 1;
|
||||
}
|
||||
ol, ul {
|
||||
list-style: none;
|
||||
}
|
||||
blockquote, q {
|
||||
quotes: none;
|
||||
}
|
||||
blockquote:before, blockquote:after,
|
||||
q:before, q:after {
|
||||
content: '';
|
||||
content: none;
|
||||
}
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
#myElement {
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
background: linear-gradient(-45deg, green, orange, blue);
|
||||
background-size: 400% 400%;
|
||||
animation: none;
|
||||
}
|
||||
|
||||
@keyframes gradient {
|
||||
0% {
|
||||
background-position: 0% 50%;
|
||||
}
|
||||
50% {
|
||||
background-position: 100% 50%;
|
||||
}
|
||||
100% {
|
||||
background-position: 0% 50%;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue