diff --git a/README.md b/README.md index 82405a6..2ed0ebd 100644 --- a/README.md +++ b/README.md @@ -15,30 +15,30 @@ To set up a racket Webserver with API landing points that interpret JSON input, | 2 | Allow for multiple landing pages associated to the API methods | done | |2.1| Web API Documentation | done | |2.2| Generate proof of success| done | -| 3 | Create a JSON processor object | started | -|3.1| JSON object Documentation | not started | -|3.2| Generate proof of success| not started | +| 3 | Create a JSON processor object | replaced - param handler class | +|3.1| JSON object Documentation | skipped | +|3.2| Generate proof of success| skipped | | 4 | Create a Server API Handler object | done | |4.1| Server API handler Documentation | done | |4.2| Generate proof of success| not-started | -| 5 | Create a Mathematics object | not started | -|5.1| Mathematics object Documentation | not started | -|5.2| Generate proof of success| not started | +| 5 | Create a Mathematics object | done | +|5.1| Mathematics object Documentation | done | +|5.2| Generate proof of success| done | | 6 | Create a Graphing object | not started | |6.1| Graphing object Documentation | not started | |6.2| Generate proof of success| not started | -|7 | Integrate objects | not started | -|7.1| Generate proof of success| not started | +|7 | Integrate objects | done | +|7.1| Generate proof of success| done | -### First Milestone Goals (04-13) -During the First Milestone we will have turned in Client related items (Items 1 - 2.2) as well as the Mathematics portion (Items 5 - 5.2) +### Second Milestone Goals +Items 3 - 4.2 , 6.1 - 7.1 ## Group Responsibilities ### Jose Flores -Will be responsible for the transmission and interpretation of data, so will be primarily working with (Items 1 - 4.2) +Will be working with a parameter handler and integrating the application (Item 3 - 4.2 , 6.1 - 7.1 ) ### Munkhjargal Narmandakh -Will be responsible for the production of results, so will be focusing on (Items 5 - 6.2) +Will be responsible for the the Graphing object (Items 6 - 6.2) ### Results & Documentation Documentation can be found in wolfracket/documentation.md diff --git a/tmp.md b/tmp.md new file mode 100644 index 0000000..14f0d35 --- /dev/null +++ b/tmp.md @@ -0,0 +1,50 @@ +# FP7-webpage Title of Project + +##Authors +Jose Flores + +Munkhjargal Narmandakh + +##Overview +To set up a racket Webserver with API landing points that interpret JSON input, which would then be processed by Racket to evaluated solutions. These solutions would then be returned by the webserver and in JSON form, images would be returned as links. + +##Screenshot +(insert a screenshot here. You may opt to get rid of the title for it. You need at least one screenshot. Make it actually appear here, don't just add a link.) + +Here's a demonstration of how to display an image that's uploaded to this repo: +![screenshot showing env diagram](withdraw.png) + +##Concepts Demonstrated +Identify the OPL concepts demonstrated in your project. Be brief. A simple list and example is sufficient. +* **Data abstraction** is used to provide access to the elements of the RSS feed. +* The objects in the OpenGL world are represented with **recursive data structures.** +* **Symbolic language processing techniques** are used in the parser. + +##External Technology and Libraries +Briefly describe the existing technology you utilized, and how you used it. Provide a link to that technology(ies). + +##Favorite Lines of Code +####Mark (a team member) +Each team member should identify a favorite line of code, expression, or procedure written by them, and explain what it does. Why is it your favorite? What OPL philosophy does it embody? +Remember code looks something like this: +```scheme +(map (lambda (x) (foldr compose functions)) data) +``` +####Lillian (another team member) +This expression reads in a regular expression and elegantly matches it against a pre-existing hashmap.... +```scheme +(let* ((expr (convert-to-regexp (read-line my-in-port))) + (matches (flatten + (hash-map *words* + (lambda (key value) + (if (regexp-match expr key) key '())))))) + matches) +``` + +##Additional Remarks +Anything else you want to say in your report. Can rename or remove this section. + +#How to Download and Run +You may want to link to your latest release for easy downloading by people (such as Mark). + +Include what file to run, what to do with that file, how to interact with the app when its running, etc. diff --git a/wolfracket/documentation.md b/wolfracket/documentation.md index a5c35f9..faa0c9f 100644 --- a/wolfracket/documentation.md +++ b/wolfracket/documentation.md @@ -51,3 +51,28 @@ generated by the server-handler class. ## json.rkt In progress. + +### math.rkt + +This is our custom math operations library, current operations allowed are... + +| method | params | returns| +|--------|--------|--------| +|'subtract| a b | a - b| +|'add | a b | a + b| +|'exponent| a b | a ^ b| +|'divide| a b | a / b| +|'prime_check| a | #t or #f | +|'nat-log| a b | a - b| +|'factorials| a | a! | +|'sinus| a | sin( a )| +|'cosh| a | cos( a )| +|'root| a | a ^ (1/2) | + +To use the class + +``` +(((my_math) method) params ...) +``` + +where method are the operations allowed by the class and params are the needed parameters for the operation. diff --git a/wolfracket/lib/api.rkt b/wolfracket/lib/api.rkt index a087a65..c95b634 100644 --- a/wolfracket/lib/api.rkt +++ b/wolfracket/lib/api.rkt @@ -4,9 +4,13 @@ ; This file holds the api. ; REQUIRES -(require web-server/servlet +(require racket/include + web-server/servlet web-server/servlet-env) +(include "param-handler.rkt") +(include "math.rkt") + ; @name api ; ; The api recieves requests from the server-handler and processes them through @@ -23,20 +27,65 @@ ; @return json the calculated output or error message (define (api) + + ; RESPONSES - ; The api documentation page + ; The API Documentation page (define (api-home req) (response/xexpr `(html (head (title "API")) (body (p "Racket Mathematics and Graphing API Project Documentation Page"))))) - ; The addition api method + ; API Function Execution + (define (api-func method param min-param req) + (response/xexpr + #:mime-type #"application/json" + (string-join (list "[" + (((param-handler) "list->string" ) + (if (param-count? min-param (((param-handler) "string->list") req + param)) + (((my_math) method) (((param-handler) "string->list") req + param)) + (list "\"error\""))) + "]") + ""))) + + (define (param-count? min-param lst) + (>= (length lst) min-param)) + + ; The API Methods (define (api-add req) - (response/xexpr - `(html (head (title "ADD")) - (body (p "Addition method"))))) + (api-func "add" "j" 2 req)) + + (define (api-subtract req) + (api-func "subtract" "j" 2 req)) + + (define (api-exponent req) + (api-func "exponent" "j" 2 req)) + + (define (api-divide req) + (api-func "divide" "j" 2 req)) + + (define (api-prime req) + (api-func "prime" "j" 1 req)) + + (define (api-logarithm req) + (api-func "logarithm" "j" 1 req)) + + (define (api-factorial req) + (api-func "factorial" "j" 1 req)) + + (define (api-sin req) + (api-func "sin" "j" 1 req)) + + (define (api-cos req) + (api-func "cos" "j" 1 req)) + + (define (api-sqrt req) + (api-func "sqrt" "j" 1 req)) + - ; The method not found page + ; The Method not found page (define (api-404 req) (response/xexpr `(html (head (title "404")) @@ -44,11 +93,20 @@ ; CONTROLLER ; Delegates which method to call - (define (controller m) - (begin (display m) - (cond ((equal? m "home") api-home) - ((equal? m "add") api-add) - (else api-404)))) + (define (controller action p) + (begin ;(set! msg m) + (cond ((equal? action "home") api-home) + ((equal? action "add") api-add) + ((equal? action "subtract") api-subtract) + ((equal? action "exponent") api-exponent) + ((equal? action "divide") api-divide) + ((equal? action "prime") api-prime) + ((equal? action "logarithm") api-logarithm) + ((equal? action "factorial") api-factorial) + ((equal? action "sin") api-sin) + ((equal? action "cos") api-cos) + ((equal? action "sqrt") api-sqrt) + (else api-404)))) controller) diff --git a/wolfracket/lib/driver.rkt b/wolfracket/lib/driver.rkt index b7e321f..4a8042a 100644 --- a/wolfracket/lib/driver.rkt +++ b/wolfracket/lib/driver.rkt @@ -17,3 +17,6 @@ ((server-handler) 'start) + + + diff --git a/wolfracket/lib/htdocs/css/main.css b/wolfracket/lib/htdocs/css/main.css new file mode 100644 index 0000000..9d05891 --- /dev/null +++ b/wolfracket/lib/htdocs/css/main.css @@ -0,0 +1,43 @@ +html, body { + margin: 0px; + padding: 0px; + font-family: helvetica; + } +div.header { + width: 100%; + height: 50px; + float:left; + background: #000; + box-shadow:1px 1px 1px #333; + } +div.title { + color:#fff; + font-size: 30px; + padding-left: 10px; + line-height: 50px; + float:left; + } +div.menu ul { + list-style-type: none; + float:left; + } +div.menu ul li { + float:left; + } +div.menu ul li a { + padding: 10px; + text-decoration: none; + color: #fff; + } +div.menu ul li a:hover { + background: #333; + text-decoration: underline; + } +div.content {} +div.footer {} +img.logo { + height: 40px; + width: 40px; + margin: 5px 15px; + float:left; + } diff --git a/wolfracket/lib/htdocs/main.css b/wolfracket/lib/htdocs/main.css new file mode 100644 index 0000000..9d05891 --- /dev/null +++ b/wolfracket/lib/htdocs/main.css @@ -0,0 +1,43 @@ +html, body { + margin: 0px; + padding: 0px; + font-family: helvetica; + } +div.header { + width: 100%; + height: 50px; + float:left; + background: #000; + box-shadow:1px 1px 1px #333; + } +div.title { + color:#fff; + font-size: 30px; + padding-left: 10px; + line-height: 50px; + float:left; + } +div.menu ul { + list-style-type: none; + float:left; + } +div.menu ul li { + float:left; + } +div.menu ul li a { + padding: 10px; + text-decoration: none; + color: #fff; + } +div.menu ul li a:hover { + background: #333; + text-decoration: underline; + } +div.content {} +div.footer {} +img.logo { + height: 40px; + width: 40px; + margin: 5px 15px; + float:left; + } diff --git a/wolfracket/lib/htdocs/main.js b/wolfracket/lib/htdocs/main.js new file mode 100644 index 0000000..ecdca2d --- /dev/null +++ b/wolfracket/lib/htdocs/main.js @@ -0,0 +1,20 @@ + +var mysubmit = function(){ + var url = "localhost:8080/api/" ; + + var method = $( "#method" ).value() ; + var num1 = $( "#num1" ).value() ; + var num2 = $( "#num2" ).value() ; + var num3 = $( "#num3" ).value() ; + + var data = { "j" : [num1 , num2 , num3 ] } ; + + $.ajax({ + url: url + method + '/' , + data: data + }).done( function( ret ) { + console.log( "done" ) ; + console.log( ret ) ; + $( "#result" ).html( ret ) ; + }); + }; diff --git a/wolfracket/lib/main.css b/wolfracket/lib/main.css new file mode 100644 index 0000000..9d05891 --- /dev/null +++ b/wolfracket/lib/main.css @@ -0,0 +1,43 @@ +html, body { + margin: 0px; + padding: 0px; + font-family: helvetica; + } +div.header { + width: 100%; + height: 50px; + float:left; + background: #000; + box-shadow:1px 1px 1px #333; + } +div.title { + color:#fff; + font-size: 30px; + padding-left: 10px; + line-height: 50px; + float:left; + } +div.menu ul { + list-style-type: none; + float:left; + } +div.menu ul li { + float:left; + } +div.menu ul li a { + padding: 10px; + text-decoration: none; + color: #fff; + } +div.menu ul li a:hover { + background: #333; + text-decoration: underline; + } +div.content {} +div.footer {} +img.logo { + height: 40px; + width: 40px; + margin: 5px 15px; + float:left; + } diff --git a/wolfracket/lib/main.js b/wolfracket/lib/main.js new file mode 100644 index 0000000..1a76021 --- /dev/null +++ b/wolfracket/lib/main.js @@ -0,0 +1,22 @@ + +var mysubmit = function(){ + var url = "../api/" ; + + var method = $( "#method" ).val() ; + var num1 = $( "#num1" ).val() ; + var num2 = $( "#num2" ).val() ; + var num3 = $( "#num3" ).val() ; + + var data = { "j" : "[" + num1 + "," + num2 + "," + num3 + "]" } ; + + $.ajax({ + url: url + method + '/' , + data: data + }).done( function( ret ) { + console.log( "done" ) ; + console.log( ret[ 0 ] ) ; + $( "#result" ).html( ret[ 0 ] ) ; + }); + + return false ; + }; diff --git a/wolfracket/lib/math.rkt b/wolfracket/lib/math.rkt new file mode 100755 index 0000000..b74704d --- /dev/null +++ b/wolfracket/lib/math.rkt @@ -0,0 +1,69 @@ + + +(require math/number-theory) +(require math) +(require math/base) +(require plot) + +(define (my_math) + + (define my_add + (lambda (lst) (list (+ (car lst) (cadr lst))))) + + (define my_subtract + (lambda (lst) (list (- (car lst) (cadr lst))))) + + (define my_multiply + (lambda (lst) (list (* (car lst) (cadr lst))))) + + (define my_divide + (lambda (lst) (list (/ (car lst) (cadr lst))))) + + (define my_exponent + (lambda (lst) (list (expt (car lst) (cadr lst))))) + + + + (define my_prime + (lambda (lst) (list (prime? (car lst))))) + + + (define my_logarithm + (lambda (lst) (list (log (car lst))))) + + (define my_factorial + (lambda (lst) (list (factorial (car lst))))) + + + + (define my_sin + (lambda (lst) (list (sin (car lst))))) + + (define my_cos + (lambda (lst) (list (cos (car lst))))) + + (define my_sqrt + (lambda (lst) (list (sqrt (car lst))))) + + + + (define (handler) + (lambda (action) + (cond ((eq? action "add") my_add) + ((eq? action "subtract") my_subtract) + ((eq? action "multiply") my_multiply) + ((eq? action "divide") my_divide) + ((eq? action "exponent") my_exponent) + + ((eq? action "prime") my_prime) + + ((eq? action "logarithm") my_logarithm) + + ((eq? action "factorial") my_factorial) + + ((eq? action "sin") my_sin) + ((eq? action "cos") my_cos) + ((eq? action "sqrt") my_sqrt) + (else #f)))) + + (handler)) diff --git a/wolfracket/lib/param-handler.rkt b/wolfracket/lib/param-handler.rkt new file mode 100644 index 0000000..0fa3a1e --- /dev/null +++ b/wolfracket/lib/param-handler.rkt @@ -0,0 +1,51 @@ +; @file param-handler.rkt +; @author Jose Flores +; +; This file holds the param-handler class. + + +(require json) +; @name param-handler +(define (param-handler) + + ; PARAMETERS + (define (get-param->string req param) + (if (eq? #f (bindings-assq (string->bytes/utf-8 param) + (request-bindings/raw req))) + "" + (bytes->string/utf-8 (binding:form-value (bindings-assq (string->bytes/utf-8 param) + (request-bindings/raw req)))))) + + (define (converter->string input) + (cond ((number? input) (number->string input)) + ((string? input) input) + ((boolean? input) (if input + "\"true\"" + "\"false\"")) + (else "error"))) + + (define (cs-string->list str) + (begin (display (jsexpr->string str)) + + (for-each (lambda (arg) + (printf "~a~n" arg)) + (string-split (substring str 1 (- (string-length str) 1)) ",")) + + (map string->number (string-split (substring str 1 (- (string-length str) 1)) ",")))) + + + (define (param->list req id) + (cs-string->list (get-param->string req id))) + + (define (list->param lst) + (string-join (map converter->string lst) ",")) + + ; CONTROLLER + ; Delegates which method to call + (define (controller m) + (begin (display m) + (cond ((equal? m "string->list") param->list) + ((equal? m "list->string") list->param) + (else "api-404")))) + + controller) diff --git a/wolfracket/lib/server-handler.rkt b/wolfracket/lib/server-handler.rkt index d652386..00a31be 100644 --- a/wolfracket/lib/server-handler.rkt +++ b/wolfracket/lib/server-handler.rkt @@ -8,8 +8,12 @@ web-server/servlet web-server/servlet-env web-server/dispatch - web-server/dispatchers/dispatch-servlets) + web-server/dispatchers/dispatch-servlets + net/url-structs + web-server/formlets/input) +(require net/url) +(require web-server/http/request-structs) ; Including the api, this is needed because the server has an api interface (include "api.rkt") @@ -31,31 +35,88 @@ ; The home page (define (home req) (response/xexpr - `(html (head (title "Home")) - (body (p "Racket Mathematics and Graphing API Project Page"))))) + `(html (head (meta ((charset "utf-8"))) + (title "Home") + (link ([rel "stylesheet"] + [type "text/css"] + [href "css/main.css"])) + (script ((src "http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"))) + (script ([type "application/javascript"] + [src "js/main.js"])) + + (body (div ((class "header")) + (div ((class "title")) + (img ([class "logo"] + [src "http://www.eecs.northwestern.edu/~robby/logos/plt-logo-red-diffuse.png"])) + "Racket Mathematics and Graphing API Project Page") + + (div ((class "menu")) + (ul (li (a ((href "/home")) "home")) + (li (a ((href "/api")) "api documentation"))))) + + (div ((class "content")) + (h2 "About the Racket Mathematics and Graphing API") + (p "The API is run by a Racket web server and uses racket to produce results. Below is a test form that can be used to see the output of the Racket API.") + (h2 "Test the API") + (form (select ((id "method")) + (option ((value "add")) "add") + (option ((value "subtract")) "subtract") + (option ((value "exponent")) "exponent") + (option ((value "divide")) "divide") + (option ((value "prime")) "prime") + (option ((value "logarithm")) "logarithm") + (option ((value "factorial")) "factorial") + (option ((value "sin")) "sin") + (option ((value "cos")) "cos") + (option ((value "sqrt")) "sqrt")) + + (input ((id "num1"))) + (input ((id "num2"))) + (input ((id "num3"))) + (button ([id "button"] + [type "button"] + [onClick "mysubmit();"]) "Submit")) + (h2 "Results") + (p ((id "result")) "Submit for a value"))))))) + ; 404 page (define (my-404 req) (response/xexpr `(html (head (title "404")) - (body (p "Resource not found."))))) + (body (p "Resource not found, api not accessed."))))) ; API INTERFACE - (define (api-interface req [method "home"]) - (begin (display method) - (((api) method) req))) + (define (api-interface req [method "home"] [param "none"]) + ;(begin (display req) + (((api) method param) req));) + ; URL DISPATCHING ; Recieve and process request (define (start request) (dispatch request)) + (define (serve-css req [arg ""]) + (response 200 #"OK" 0 #"text/css" empty (lambda (op) + (with-input-from-file arg (lambda () (copy-port + (current-input-port) op)))))) + + (define (serve-js req [arg ""]) + (response 200 #"OK" 0 #"application/javascript" empty (lambda (op) + (with-input-from-file arg (lambda () (copy-port + (current-input-port) op)))))) + ; Determine url (define-values (dispatch url) + (begin (display url) (dispatch-rules [("home") home] + [("css" (string-arg)) serve-css] + [("js" (string-arg)) serve-js] [("api") api-interface] [("api" (string-arg)) api-interface] - [else my-404])) + [("api" (string-arg) (string-arg)) api-interface] + [else my-404]))) ; SERVER ; start server @@ -63,7 +124,8 @@ (serve/servlet start #:port 8080 #:listen-ip #f ; listen for external requests - #:servlet-path "" + #:servlet-path "/" + #:extra-files-paths (list "./htdocs") #:servlet-regexp #rx"")) ; CONTROLLER diff --git a/wolfracket/project-plan.md b/wolfracket/project-plan.md new file mode 100644 index 0000000..7da42cb --- /dev/null +++ b/wolfracket/project-plan.md @@ -0,0 +1,52 @@ +# WOLFRACKET +### A Racket Mathematics and Graphing REST API + +## Purpose +To set up a racket Webserver with API landing points that interpret JSON input, which would then be processed by Racket to evaluated solutions. These solutions would then be returned by the webserver and in JSON form, images would be returned as links. + +## Work Plan and Schedule +### Plan + +| | task | state | +|---|------|-------| +| 1 | Create Web Server object | done | +|1.1| Web Server Documentation | done | +|1.2| Generate proof of success| done | +| 2 | Allow for multiple landing pages associated to the API methods | done | +|2.1| Web API Documentation | done | +|2.2| Generate proof of success| done | +| 3 | Create a JSON processor object | started | +|3.1| JSON object Documentation | not started | +|3.2| Generate proof of success| not started | +| 4 | Create a Server API Handler object | done | +|4.1| Server API handler Documentation | done | +|4.2| Generate proof of success| not-started | +| 5 | Create a Mathematics object | done | +|5.1| Mathematics object Documentation | done | +|5.2| Generate proof of success| done | +| 6 | Create a Graphing object | not started | +|6.1| Graphing object Documentation | not started | +|6.2| Generate proof of success| not started | +|7 | Integrate objects | not started | +|7.1| Generate proof of success| not started | + +### First Milestone Goals (04-13) +During the First Milestone we will have turned in Client related items (Items 1 - 2.2) as well as the Mathematics portion (Items 5 - 5.2) + +## Group Responsibilities +### Jose Flores +Will be responsible for the transmission and interpretation of data, so will be primarily working with (Items 1 - 4.2) + +### Munkhjargal Narmandakh +Will be responsible for the production of results, so will be focusing on (Items 5 - 6.2) + +### Results & Documentation +Documentation can be found in wolfracket/documentation.md + +Proof of concepts can be found in wolfracket/test-results.md + + +[piazza]: https://piazza.com/class/i55is8xqqwhmr?cid=453 +[markdown]: https://help.github.com/articles/markdown-basics/ +[json]: http://jsonlint.com/ +[proposal]: https://docs.google.com/presentation/d/1jA6KDpAIbmpuTRilt6YqcnbVv8tDG9p0BZxEkVU0yhk/edit#slide=id.p diff --git a/wolfracket/test-results.md b/wolfracket/test-results.md index 69f2ddd..cd1010d 100644 --- a/wolfracket/test-results.md +++ b/wolfracket/test-results.md @@ -43,6 +43,47 @@ localhost:8080/api/not-a-valid-page API Resource not found. ``` +## Mathematical operations +### math.rkt +``` +(((my_math) 'add) 1 2) +``` + +3 + +``` +(((my_math) 'subtract) 1 2) +``` + +-1 + +``` +(((my_math) 'exponent) 1 2) +``` + +1 + +``` +(((my_math) 'prime_check) 1) +``` +false (here is wrong result) + +``` +(((my_math) 'divide) 1 2) +``` + +1/2 +``` +(((my_math) 'factorials) 12) +``` + +479001600 +(here is wrong result) + +``` +(((my_math) 'sinus) 2) +``` +3.626860407847019