Created report

I didn't forget this time
This commit is contained in:
Doug-Richardson 2017-04-28 09:35:22 -04:00 committed by GitHub
parent 3cfff385f1
commit 5c89715942

144
Douglas_Richardson.md Normal file
View File

@ -0,0 +1,144 @@
# Hermes project report
## Douglas Richardson
### April 28, 2017
# Overview
Hermes is a multi-user chat program that allows users to setup a server, connect to it
and communicate with all other members of the server.
Hermes uses TCP pipes to tread input and output like a port. Essentially, each client sends
information to the server and depending on the input, the server decides what to do with it
and usually sends output back to all the other users.
# Libraries Used
The code uses two non-default libraries:
```
(require racket/gui/base)
(require math/base)
```
* The ```racket/gui/base``` library is the primary library for the GUI.
* the ```math/base``` is used for random number generation.
# Key Code Excerpts
Here is a discussion of the most essential procedures, including a description of how they embody ideas from
UMass Lowell's COMP.3010 Organization of Programming languages course.
Five examples are shown and they are individually numbered.
## 1. Initializing the gui
This line of code allows us to wrap the gui into an object.
```
(define (make-gui)
...
(cond ((eq? command 'show) (lambda () (send main-frame show #t)))
((eq? command 'get-color) get-my-color)
((eq? command 'set-color) set-color)
((eq? command 'prompt-color) prompt-color)
((eq? command 'prompt-username) prompt-username)
((eq? command 'prompt-hostname) prompt-hostname)
((eq? command 'send) send-message) ;; call to show a message in a gui
((eq? command 'set-name) (lambda (newname) (if (string? newname)
(set! name newname)
(print "Thats not good"))))
; ((eq? command 'recieve-message) user-message)
; ((eq? command 'get-list) listy)
; ((eq? command 'set-list) update)
;;Something up with that
; else should assume a message and output to screen we do not want it
; to fail
((eq? command 'get-message) get-message)
(else (error "Invalid Request" command))
))
;;dispatch goes below that
dispatch)```
This allows us to make our code simpler and lets us treat the gui like an object in it's self.
Giving the gui commands to change it's self rather than having to remember all the commands it has.
## 2. Working with lists
This code is code that allows us to append a new message onto the end of the list of messages using recursion
```
(define (appendlist listoflist add-to-end)
(if (null? listoflist)
(cons add-to-end '())
(cons (car listoflist) (appendlist (cdr listoflist) add-to-end))))```
Normally there is a function to just append onto the end of a list, however the problem is that if we attempt to append
a list of elements onto the end of a list, it just appends the elements onto the end of the list. For example if I had
a list of the following '(("Doug" "Hello World!" "Purple"))
and wanted to append the list '("Gordon" "No one else is here Doug." "Black") The list I want back would be
'(("Doug" "Hello World!" "Purple")("Gordon" "No one else is here Doug." "Black")) but if I use the default
list append I get'(("Doug" "Hello World!" "Purple")"Gordon" "No one else is here Doug." "Black")
which is no good for the gui.
This follows on our idea of working with lists and using recursion to walk down a list.
## 3. Re-drawing messages
The following procedure is used to re-draw messages onto the canvas after a screen move or resize.
```
(define (update-helper given-list)
(if (null? given-list)
'()
(if (null? (car given-list))
'()
(begin (user-message
(get-username-from-list (car given-list))
(get-message-from-list (car given-list))
(get-color-from-list (car given-list)))
(update-helper (cdr given-list))))))```
While it doesn't actually use the map function, this is a map as for every element of a list (each element is a list of three strings)
it runs a procedure (or in this case a set of procedures) in the order of the list.
## 4. Parsing Messages
This line of code is used to parse a single string message into a three string message
```
(define (user-message-parse string-i start)
(define (helper str index)
(if (eq? (string-ref str (+ start index)) #\~) ; regexes would allow us
; to avoid this #\~
(substring str start (+ start index))
(helper str (+ index 1))))
(helper string-i 0))```
This was used to parse a string into smaller strings. In hermes we can only send one string to each client at one time, therefore
the three elements that the gui uses to print messages need to be compressed together. We append a ~ inbetween each of these so we can
parse them out at the client end.
While we don't run any commands off it (saved that part for the commands we do interpret from strings)
it is similar to the symbolic differentaitor.
## 5. Color setting
Here we have an example of when we use a symbolic differentiator in the gui to determine when a user wants to run a command
rather than input text.
```
(define (button-do-stuff b e);b and e do nothing :/
(if (color-change-request? (send input get-value))
(set! my-color (get-color-from-input (send input get-value)))
...
(define (color-change-request? given-string)
(if (> (string-length given-string) 7)
(if (equal? (substring given-string 0 6) "/color")
#t
#f)
#f))```
The procedure button-do-stuff is run every time the user presses the return key or presses the send button on the gui
and what it will do is check to see if the user typed in "/color", and if they did it sets the internal color to be
what the user said after that. This is part of our symbolic differentiator that allows the user to use commands
rather than the typical use of the input (which is just to send a message to other clients)