commit 198b5dc62bcfdb73443cf7f55fc768f97a5488f3 Author: rita Date: Sun Oct 13 22:03:58 2019 +0200 first diff --git a/Chat server and client/chat_client.py b/Chat server and client/chat_client.py new file mode 100644 index 0000000..cb0ac55 --- /dev/null +++ b/Chat server and client/chat_client.py @@ -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() diff --git a/Chat server and client/chat_server.py b/Chat server and client/chat_server.py new file mode 100644 index 0000000..cbff6aa --- /dev/null +++ b/Chat server and client/chat_server.py @@ -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() diff --git a/Chat server and client/simplerequest/chat_server.py b/Chat server and client/simplerequest/chat_server.py new file mode 100644 index 0000000..a322a66 --- /dev/null +++ b/Chat server and client/simplerequest/chat_server.py @@ -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() diff --git a/Chat server and client/simplerequest/client.py b/Chat server and client/simplerequest/client.py new file mode 100644 index 0000000..ff3d801 --- /dev/null +++ b/Chat server and client/simplerequest/client.py @@ -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() diff --git a/Chat server and client/xpubchat.png b/Chat server and client/xpubchat.png new file mode 100644 index 0000000..dd45666 Binary files /dev/null and b/Chat server and client/xpubchat.png differ diff --git a/Clickbait bot/LICENSE.txt b/Clickbait bot/LICENSE.txt new file mode 100644 index 0000000..64556d3 --- /dev/null +++ b/Clickbait bot/LICENSE.txt @@ -0,0 +1,112 @@ +Free Art License 1.3 (FAL 1.3) + +Preamble + +The Free Art License grants the right to freely copy, distribute, and transform creative works without infringing the author’s rights. + +The Free Art License recognizes and protects these rights. Their implementation has been reformulated in order to allow everyone to use creations of the human mind in a creative manner, regardless of their types and ways of expression. + +While the public’s access to creations of the human mind usually is restricted by the implementation of copyright law, it is favoured by the Free Art License. This license intends to allow the use of a work’s resources; to establish new conditions for creating in order to increase creation opportunities. The Free Art License grants the right to use a work, and acknowledges the right holder’s and the user’s rights and responsibility. + +The invention and development of digital technologies, Internet and Free Software have changed creation methods: creations of the human mind can obviously be distributed, exchanged, and transformed. They allow to produce common works to which everyone can contribute to the benefit of all. + +The main rationale for this Free Art License is to promote and protect these creations of the human mind according to the principles of copyleft: freedom to use, copy, distribute, transform, and prohibition of exclusive appropriation. + +Definitions + +« work » either means the initial work, the subsequent works or the common work as defined hereafter: + +« common work » means a work composed of the initial work and all subsequent contributions to it (originals and copies). The initial author is the one who, by choosing this license, defines the conditions under which contributions are made. + +« Initial work » means the work created by the initiator of the common work (as defined above), the copies of which can be modified by whoever wants to + +« Subsequent works » means the contributions made by authors who participate in the evolution of the common work by exercising the rights to reproduce, distribute, and modify that are granted by the license. + +« Originals » (sources or resources of the work) means all copies of either the initial work or any subsequent work mentioning a date and used by their author(s) as references for any subsequent updates, interpretations, copies or reproductions. + +« Copy » means any reproduction of an original as defined by this license. + +1. OBJECT +The aim of this license is to define the conditions under which one can use this work freely. + +2. SCOPE +This work is subject to copyright law. Through this license its author specifies the extent to which you can copy, distribute, and modify it. + +2.1 FREEDOM TO COPY (OR TO MAKE REPRODUCTIONS) +You have the right to copy this work for yourself, your friends or any other person, whatever the technique used. + +2.2 FREEDOM TO DISTRIBUTE, TO PERFORM IN PUBLIC +You have the right to distribute copies of this work; whether modified or not, whatever the medium and the place, with or without any charge, provided that you: +attach this license without any modification to the copies of this work or indicate precisely where the license can be found, +specify to the recipient the names of the author(s) of the originals, including yours if you have modified the work, +specify to the recipient where to access the originals (either initial or subsequent). +The authors of the originals may, if they wish to, give you the right to distribute the originals under the same conditions as the copies. + +2.3 FREEDOM TO MODIFY +You have the right to modify copies of the originals (whether initial or subsequent) provided you comply with the following conditions: +all conditions in article 2.2 above, if you distribute modified copies; +indicate that the work has been modified and, if it is possible, what kind of modifications have been made; +distribute the subsequent work under the same license or any compatible license. +The author(s) of the original work may give you the right to modify it under the same conditions as the copies. + +3. RELATED RIGHTS +Activities giving rise to author’s rights and related rights shall not challenge the rights granted by this license. +For example, this is the reason why performances must be subject to the same license or a compatible license. Similarly, integrating the work in a database, a compilation or an anthology shall not prevent anyone from using the work under the same conditions as those defined in this license. + +4. INCORPORATION OF THE WORK +Incorporating this work into a larger work that is not subject to the Free Art License shall not challenge the rights granted by this license. +If the work can no longer be accessed apart from the larger work in which it is incorporated, then incorporation shall only be allowed under the condition that the larger work is subject either to the Free Art License or a compatible license. + +5. COMPATIBILITY +A license is compatible with the Free Art License provided: +it gives the right to copy, distribute, and modify copies of the work including for commercial purposes and without any other restrictions than those required by the respect of the other compatibility criteria; +it ensures proper attribution of the work to its authors and access to previous versions of the work when possible; +it recognizes the Free Art License as compatible (reciprocity); +it requires that changes made to the work be subject to the same license or to a license which also meets these compatibility criteria. + +6. YOUR INTELLECTUAL RIGHTS +This license does not aim at denying your author’s rights in your contribution or any related right. By choosing to contribute to the development of this common work, you only agree to grant others the same rights with regard to your contribution as those you were granted by this license. Conferring these rights does not mean you have to give up your intellectual rights. + +7. YOUR RESPONSIBILITIES +The freedom to use the work as defined by the Free Art License (right to copy, distribute, modify) implies that everyone is responsible for their own actions. + +8. DURATION OF THE LICENSE +This license takes effect as of your acceptance of its terms. The act of copying, distributing, or modifying the work constitutes a tacit agreement. This license will remain in effect for as long as the copyright which is attached to the work. If you do not respect the terms of this license, you automatically lose the rights that it confers. +If the legal status or legislation to which you are subject makes it impossible for you to respect the terms of this license, you may not make use of the rights which it confers. + +9. VARIOUS VERSIONS OF THE LICENSE +This license may undergo periodic modifications to incorporate improvements by its authors (instigators of the « Copyleft Attitude » movement) by way of new, numbered versions. +You will always have the choice of accepting the terms contained in the version under which the copy of the work was distributed to you, or alternatively, to use the provisions of one of the subsequent versions. + +10. SUB-LICENSING +Sub-licenses are not authorized by this license. Any person wishing to make use of the rights that it confers will be directly bound to the authors of the common work. + +11. LEGAL FRAMEWORK +This license is written with respect to both French law and the Berne Convention for the Protection of Literary and Artistic Works. + +USER GUIDE + +– How to use the Free Art License? +To benefit from the Free Art License, you only need to mention the following elements on your work: +[Name of the author, title, date of the work. When applicable, names of authors of the common work and, if possible, where to find the originals]. +Copyleft: This is a free work, you can copy, distribute, and modify it under the terms of the Free Art License http://artlibre.org/licence/lal/en/ + +– Why to use the Free Art License? +1.To give the greatest number of people access to your work. +2.To allow it to be distributed freely. +3.To allow it to evolve by allowing its copy, distribution, and transformation by others. +4.So that you benefit from the resources of a work when it is under the Free Art License: to be able to copy, distribute or transform it freely. +5.But also, because the Free Art License offers a legal framework to disallow any misappropriation. It is forbidden to take hold of your work and bypass the creative process for one’s exclusive possession. + +– When to use the Free Art License? +Any time you want to benefit and make others benefit from the right to copy, distribute and transform creative works without any exclusive appropriation, you should use the Free Art License. You can for example use it for scientific, artistic or educational projects. + +– What kinds of works can be subject to the Free Art License? +The Free Art License can be applied to digital as well as physical works. +You can choose to apply the Free Art License on any text, picture, sound, gesture, or whatever sort of stuff on which you have sufficient author’s rights. + +– Historical background of this license: +It is the result of observing, using and creating digital technologies, free software, the Internet and art. It arose from the « Copyleft Attitude » meetings which took place in Paris in 2000. For the first time, these meetings brought together members of the Free Software community, artists, and members of the art world. The goal was to adapt the principles of Copyleft and free software to all sorts of creations. http://www.artlibre.org + +Copyleft Attitude, 2007. +You can make reproductions and distribute this license verbatim (without any changes). \ No newline at end of file diff --git a/Clickbait bot/clickbait-generator.png b/Clickbait bot/clickbait-generator.png new file mode 100644 index 0000000..a622db0 Binary files /dev/null and b/Clickbait bot/clickbait-generator.png differ diff --git a/Clickbait bot/clickbait-generator2.png b/Clickbait bot/clickbait-generator2.png new file mode 100644 index 0000000..9b5d0d0 Binary files /dev/null and b/Clickbait bot/clickbait-generator2.png differ diff --git a/Clickbait bot/doctor.html b/Clickbait bot/doctor.html new file mode 100644 index 0000000..e69de29 diff --git a/Clickbait bot/doctor.js b/Clickbait bot/doctor.js new file mode 100644 index 0000000..369faba --- /dev/null +++ b/Clickbait bot/doctor.js @@ -0,0 +1,16 @@ +eliza({"final": "Goodbye. Go get coins.", +"synon": ["belief feel think believe wish", +"family mother mom father dad sister brother wife children child", +"desire want need", +"sad unhappy depressed sick", +"happy elated glad better", "cannot can't", +"everyone everybody nobody noone", +"sorry apologise", +"be am is are was"], +"post": [""], "keywords": [ +{"token": "xnone", "rules": [{"decomp": "*", "reasmb": ["You won't believe (1) *scandal*", "(1), IT’S OFFICIAL.", "(1), WEIRD!!!!", "(1), DRASTIC!!!"]}], "weight": 0}, +{"token": "?", "rules": [{"decomp": "*", "reasmb": ["a question"]}], "weight": 0}, +{"token": "sorry", "rules": [{"decomp": "*", "reasmb": ["You won't believe who is sorry! *EMOTIONAL*", "She apologised! *EMOTIONAL*"]}], "weight": 0}, +{"token": "dream", "rules": [{"decomp": "*", "reasmb": ["MY CRAZY DREAMS!!!! You won’t believe this."]}], "weight": 4}, +{"token": "question", "rules": [{"decomp": "*", "reasmb": ["(1) ????????? SHOCKED!"]}], "weight": 1},], +"initial": "Write your post title:", "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"], "quit": []}); diff --git a/Clickbait bot/doctor.json b/Clickbait bot/doctor.json new file mode 100644 index 0000000..9189574 --- /dev/null +++ b/Clickbait bot/doctor.json @@ -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." +} diff --git a/Clickbait bot/doctor.txt b/Clickbait bot/doctor.txt new file mode 100644 index 0000000..efcc622 --- /dev/null +++ b/Clickbait bot/doctor.txt @@ -0,0 +1,41 @@ +initial: Tell me your post title. +final: Goodluck. Go get coins. +quit: bye +quit: goodbye +quit: quit +pre: dont don't +pre: cant can't +pre: wont won't +pre: recollect remember +pre: dreamt dreamed +pre: dreams dream +pre: maybe perhaps +pre: how what +pre: when what +pre: certainly yes +pre: machine computer +pre: computers computer +pre: were was +pre: you're you are +pre: i'm i am +pre: same alike +synon: belief feel think believe wish +synon: sad unhappy depressed sick +synon: sorry apologise +key: xnone + decomp: * + reasmb: You won't believe (1) *scandal* + reasmb: (1) IT’S OFFICIAL. + reasmb: (1) WEIRD!!!! +key: ? + decomp: * ? + reasmb: (1) ????????? SHOCKED! + reasmb: (1) ????????? (DRASTIC) + reasmb: (1) ????????? (no clickbait) +key: sorry + decomp: * + reasmb: You won't believe who is sorry! *EMOTIONAL* + reasmb: He apologised! *EMOTIONAL* +key: dreamed + decomp: * + reasmb: MY CRAZY DREAMS!!!! You won’t believe this. diff --git a/Clickbait bot/eliza.js b/Clickbait bot/eliza.js new file mode 100644 index 0000000..eb7d7db --- /dev/null +++ b/Clickbait bot/eliza.js @@ -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 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 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 + + + CLICKBAIT GENERATOR + + + + +
+
+
+
+ +
+
+ + + + + diff --git a/Clickbait bot/eliza_script_to_json.py b/Clickbait bot/eliza_script_to_json.py new file mode 100644 index 0000000..e94768b --- /dev/null +++ b/Clickbait bot/eliza_script_to_json.py @@ -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)) diff --git a/Clickbait bot/instructions.txt b/Clickbait bot/instructions.txt new file mode 100644 index 0000000..3881a0b --- /dev/null +++ b/Clickbait bot/instructions.txt @@ -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". + diff --git a/Clickbait bot/jsonp.py b/Clickbait bot/jsonp.py new file mode 100644 index 0000000..acfe371 --- /dev/null +++ b/Clickbait bot/jsonp.py @@ -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))) diff --git a/Clickbait bot/makefile b/Clickbait bot/makefile new file mode 100644 index 0000000..da89d06 --- /dev/null +++ b/Clickbait bot/makefile @@ -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 > $@ diff --git a/Scraping and Filtering News/categorization.py b/Scraping and Filtering News/categorization.py new file mode 100755 index 0000000..9512f86 --- /dev/null +++ b/Scraping and Filtering News/categorization.py @@ -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 + "
") + break + +text_file = open("trump_news.htm", "w+") +text_file.write("".join(trump_list)) +# print("".join(happy_list)) +# Close the file +file.close() diff --git a/Scraping and Filtering News/results.txt b/Scraping and Filtering News/results.txt new file mode 100644 index 0000000..7836eca --- /dev/null +++ b/Scraping and Filtering News/results.txt @@ -0,0 +1,4 @@ +Impeachment has put Trump in a different place. He’s showing it every day. +No refugees allowed? Trump’s plan to give states and cities a veto prompts an outcry. +‘You had your help’: At rally, Trump supporters back Syria withdrawal +She began to talk — then mysteriously fell silent. Months later, her parents learned why. \ No newline at end of file diff --git a/Scraping and Filtering News/scrape_titles.py b/Scraping and Filtering News/scrape_titles.py new file mode 100644 index 0000000..cfe847c --- /dev/null +++ b/Scraping and Filtering News/scrape_titles.py @@ -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 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() diff --git a/Scraping and Filtering News/trump.txt b/Scraping and Filtering News/trump.txt new file mode 100755 index 0000000..a0ab413 --- /dev/null +++ b/Scraping and Filtering News/trump.txt @@ -0,0 +1 @@ +Trump diff --git a/Scraping and Filtering News/trump_news.htm b/Scraping and Filtering News/trump_news.htm new file mode 100644 index 0000000..d5672ea --- /dev/null +++ b/Scraping and Filtering News/trump_news.htm @@ -0,0 +1,3 @@ +Impeachment has put Trump in a different place. He’s showing it every day. +
‘You had your help’: At rally, Trump supporters back Syria withdrawal +
\ No newline at end of file diff --git a/Touch 2tap/index.htm b/Touch 2tap/index.htm new file mode 100644 index 0000000..14f3685 --- /dev/null +++ b/Touch 2tap/index.htm @@ -0,0 +1,48 @@ + + + + + Double tap + + + + + + + + + + + +
+ + + + + + diff --git a/Touch 2tap/reset.css b/Touch 2tap/reset.css new file mode 100644 index 0000000..ed11813 --- /dev/null +++ b/Touch 2tap/reset.css @@ -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; +} diff --git a/Touch 2tap/style.css b/Touch 2tap/style.css new file mode 100644 index 0000000..48103b7 --- /dev/null +++ b/Touch 2tap/style.css @@ -0,0 +1,6 @@ +#myElement { + background-image: linear-gradient(pink, red); + height: 100vh; + text-align: center; + font: 30px/300px Arial, sans-serif; +} diff --git a/Touch 2tap/tap.jpg b/Touch 2tap/tap.jpg new file mode 100644 index 0000000..771b4c8 Binary files /dev/null and b/Touch 2tap/tap.jpg differ diff --git a/Touch panup/index.htm b/Touch panup/index.htm new file mode 100644 index 0000000..ce2960e --- /dev/null +++ b/Touch panup/index.htm @@ -0,0 +1,38 @@ + + + + + Pan up + + + + + + + + + + + +
+ + + + diff --git a/Touch panup/panup.jpg b/Touch panup/panup.jpg new file mode 100644 index 0000000..4e63dce Binary files /dev/null and b/Touch panup/panup.jpg differ diff --git a/Touch panup/reset.css b/Touch panup/reset.css new file mode 100644 index 0000000..ed11813 --- /dev/null +++ b/Touch panup/reset.css @@ -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; +} diff --git a/Touch panup/style.css b/Touch panup/style.css new file mode 100644 index 0000000..c205c73 --- /dev/null +++ b/Touch panup/style.css @@ -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%; + } +}