diff --git a/.gitignore b/.gitignore index a3098a47..bd49bee4 100644 --- a/.gitignore +++ b/.gitignore @@ -14,4 +14,6 @@ flask_project/venv flask_project/ven/bin/ flask_project/venv/include/ flask_project/ven/lib -numpy.ipynb \ No newline at end of file +numpy.ipynb +.ipynb_checkpoints +.vscode/ \ No newline at end of file diff --git a/python_for_web/app.py b/python_for_web/app.py index c9059fb3..ecd99411 100644 --- a/python_for_web/app.py +++ b/python_for_web/app.py @@ -3,6 +3,10 @@ import os # importing operating system module app = Flask(__name__) +# to stop caching static file +app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0 + + @app.route('/') # this decorator create the home route def home (): @@ -15,12 +19,19 @@ def about(): name = '30 Days Of Python Programming' return render_template('about.html', name = name, title = 'About Us') +@app.route('/result') +def result(): + return render_template('result.html') + @app.route('/post', methods= ['GET','POST']) def post(): name = 'Text Analyzer' - return render_template('post.html', name = name, title = name) - - + if request.method == 'GET': + return render_template('post.html', name = name, title = name) + if request.method =='POST': + content = request.form['content'] + return redirect(url_for('result')) + if __name__ == '__main__': # for deployment # to make it work for both production and development diff --git a/python_for_web/static/css/main.css b/python_for_web/static/css/main.css index efa9c7ba..cf7c09bd 100644 --- a/python_for_web/static/css/main.css +++ b/python_for_web/static/css/main.css @@ -1,31 +1,44 @@ +/* === GENERAL === */ + * { margin: 0; padding: 0; box-sizing: border-box; } +/* === css variables === */ :root { --header-bg-color: #4a7799; - --textarea-bg-color: rgb(235, 231, 231); - --body-bg-color: rgb(225, 228, 230); - --nav-link-color:#aaa; + --textarea-bg-color: rgb(250, 246, 246); + --body-bg-color: rgb(210, 214, 210); + --nav-link-color: #bbb; } +/* === body style === */ body { background: var(--body-bg-color); margin: auto; - line-height: 1.5; + line-height: 1.75; + font-weight: 900; + word-spacing: 1.5px; + font-family: 'Lato',sans-serif; + font-weight: 300; } +/* === header style === */ header { background: var(--header-bg-color); } - +/* === title and subtitle style === */ h1, h2 { - margin: 25px; + margin: 20px; + font-weight: 300; + font-family: Nunito; } +/* === header menu style === */ + .menu-container { width: 90%; display: flex; @@ -39,10 +52,6 @@ h2 { display: flex; } -li { - list-style: none; -} - .nav-list { list-style: none; margin: 0 5px; @@ -53,39 +62,98 @@ li { font-size: 22px; padding: 0 5px; color: var(--nav-link-color); + font-weight: 400; } +.brand-name { + font-size: 28px; + font-weight: bolder; +} +/* === paragraph text style === */ +p { + font-size: 22px; + font-weight: 300; +} + +/* === main style === */ main { width: 90%; margin: auto; - text-align: center; } -.btn{ +/* === container div inside main style === */ + +.container { + background: rgb(210, 214, 210); + padding: 20px; + margin: auto; +} + +.tech-lists { + margin: 10px auto; + text-align: left; + font-size: 20px; +} +.tech { + list-style: none; +} +/* === button style === */ +.btn { width: 150px; height: 50px; background: var(--header-bg-color); color: var(--nav-link-color); font-size: 20px; - margin:5px; + margin: 5px; border: 1px solid var(--header-bg-color); + font-family: Lato; + cursor: pointer; } .btn:focus { outline: 2px solid #2a70a5; + cursor: pointer; } - - +/* === textarea style === */ textarea { - padding: 20px; - outline: 1px solid var(--nav-link-color); + width: 65%; + margin: auto; + padding: 10px 15px; + outline: 2px solid rgba(207, 203, 203, 0.25); border: none; font-size: 18px; + font-family: Lato; + font-weight: 300; } textarea:focus { border: none; - outline: 2px solid #4a7799; + outline: 2px solid rgba(74, 119, 153, 0.45); background: var(--textarea-bg-color); font-size: 18px; + caret-color: var(--header-bg-color); + font-family: Lato; + font-weight: 300; + +} + +/* === responsiveness === */ +@media (max-width:600px) { + + .menu-container { + flex-direction: column; + justify-content: space-between; + } + h1{ + font-size: 22px; + } + + .nav-lists { + flex-direction: column; + } + + textarea { + width: 100%; + } + } \ No newline at end of file diff --git a/python_for_web/templates/about.html b/python_for_web/templates/about.html index 26ac0d95..52d4d890 100644 --- a/python_for_web/templates/about.html +++ b/python_for_web/templates/about.html @@ -1,7 +1,9 @@ {% extends 'layout.html' %} {% block content %} -

About Us

-

{{name}}

-

This is a 30 days of python programming challenge. If you have been coding this far, you are awesome. Congratulations - for the job well done!

+
+

About {{name}}

+

This is a 30 days of python programming challenge. If you have been coding this far, you are awesome. + Congratulations + for the job well done!

+
{% endblock %} \ No newline at end of file diff --git a/python_for_web/templates/home.html b/python_for_web/templates/home.html index 284b9138..23fa18d3 100644 --- a/python_for_web/templates/home.html +++ b/python_for_web/templates/home.html @@ -1,11 +1,17 @@ {% extends 'layout.html' %} {% block content %} -

Welcome to {{name}}

-

You need the following technologies to build this web application:

- {% endblock %} \ No newline at end of file diff --git a/python_for_web/templates/layout.html b/python_for_web/templates/layout.html index fdf5a117..1966e0bd 100644 --- a/python_for_web/templates/layout.html +++ b/python_for_web/templates/layout.html @@ -4,7 +4,9 @@ - + + {% if title %} 30 Days of Python - {{ title}} {% else %} @@ -16,19 +18,19 @@
- +
- {% block content %} {% endblock %} + {% block content %} {% endblock %}
diff --git a/python_for_web/templates/post.html b/python_for_web/templates/post.html index d351961e..ff2ffa7c 100644 --- a/python_for_web/templates/post.html +++ b/python_for_web/templates/post.html @@ -1,9 +1,17 @@ {% extends 'layout.html' %} {% block content %} -

Text Analyzer

-
- -
- - +
+

Text Analyzer

+
+
+ +
+
+ +
+ + +
+
+ {% endblock %} \ No newline at end of file diff --git a/python_for_web/templates/result.html b/python_for_web/templates/result.html index 4c29ce6d..592e7dfa 100644 --- a/python_for_web/templates/result.html +++ b/python_for_web/templates/result.html @@ -1,5 +1,8 @@ {% extends 'layout.html' %} {% block content %} -

Result

+
+

Text Analysis Result

+
+ {% endblock %} \ No newline at end of file diff --git a/readme25-27.md b/readme25-27.md index 1b63a51c..42be06ef 100644 --- a/readme25-27.md +++ b/readme25-27.md @@ -790,12 +790,34 @@ Python is a general purpose programming language and it can be used for many pla Flask is a web development framework written in python. Flask uses Jinja2 template engine. Flask can be also used with other modern frond libraries such as react. If you did not install the virtualenv package ye install it first. Virtual environment will allows to isolate project dependencies. -Follow, the following steps to get started with Flask +After completing all the step your project file structure should look like this: +```sh + +├── Procfile +├── app.py +├── env +│   ├── bin +├── requirements.txt +├── static +│   └── css +│   └── main.css +└── templates + ├── about.html + ├── home.html + ├── layout.html + ├── post.html + └── result.html +``` + +Follow, the following steps to get started with Flask. +Step 1: install virtualenv using the following command. ```sh pip install virtualenv ``` +Step 2: + ```sh asabeneh@Asabeneh:~/Desktop$ mkdir python_for_web asabeneh@Asabeneh:~/Desktop$ cd python_for_web/ @@ -812,8 +834,9 @@ MarkupSafe==1.1.1 Werkzeug==0.16.0 (env) asabeneh@Asabeneh:~/Desktop/python_for_web$ ``` +We created a project director named python_for_web. Inside the project we created a virtual environment *env* which could be any name but I prefer to call it *env*. Then we activated the virtual environment. We used pip freeze to check the installed packages in the project directory. The result of pip freeze was empty because a package was not installed yet. -Now, let's create app.py file in the project directory and write the following code. The following code has flask module, os module. +Now, let's create app.py file in the project directory and write the following code. The app.py file will be the main file in the project. The following code has flask module, os module. The home route. @@ -862,7 +885,6 @@ def home (): def about(): return '

About us

' - if __name__ == '__main__': port = int(os.environ.get("PORT", 5000)) # for deployment # to make it work for both production and development @@ -928,12 +950,10 @@ def about(): return render_template('about.html') if __name__ == '__main__': - port = int(os.environ.get("PORT", 5000)) # for deployment + # for deployment we use the environ # to make it work for both production and development - if port == 5000: - app.run(debug=True) - else: - app.run(port = port) # to listen to the port + port = int(os.environ.get("PORT", 5000)) + app.run(debug=True, host='0.0.0.0', port=port) ``` As you can see to go to different pages or to navigate we need a navigation. Let's add a link to each page or let's create a layout which we use to every page. @@ -967,7 +987,7 @@ def about(): name = '30 Days Of Python Programming' return render_template('about.html', name = name, title = 'About Us') -@app.route('/post', methods= ['GET','POST']) +@app.route('/post') def post(): name = 'Text Analyzer' return render_template('post.html', name = name, title = name) @@ -1038,66 +1058,149 @@ layout.html ```html - - - + + + + + + {% if title %} 30 Days of Python - {{ title}} {% else %} 30 Days of Python {% endif %} - + - +
- + + +
- {% block content %} {% endblock %} + {% block content %} {% endblock %}
- + + ``` -Now, lets remove all the repeated code in the other template files and import the layout.html +Now, lets remove all the repeated code in the other template files and import the layout.html. The href is using *url_for* function with the name of the route function to connect each navigation route. home.html ```html -{% extends 'layout.html' %} {% block content %} -

Welcome to {{name}}

-

You need the following technologies to build this web application:

-{% for tech in techs %} - -{% endfor %} {% endblock %} +{% extends 'layout.html' %} +{% block content %} +
+

Welcome to {{name}}

+

This application clean texts and analyse the number of word, characters and most frequent words in the text. + Check it out by click text analyzer at the menu. + You need the following technologies to build this web application:

+ +
+ +{% endblock %} ``` about.html ```html -{% extends 'layout.html' %} {% block content %} -

About Us

-

{{name}}

+{% extends 'layout.html' %} +{% block content %} +
+

About {{name}}

+

This is a 30 days of python programming challenge. If you have been coding this far, you are awesome. + Congratulations + for the job well done!

+
{% endblock %} ``` post.html ```html -{% extends 'layout.html' %} {% block content %} -

Text Analyzer

- -
- +{% extends 'layout.html' %} +{% block content %} +
+

Text Analyzer

+
+
+ +
+
+ +
+ + +
+
+ {% endblock %} ``` +Request methods, there are different request methods(GET, POST, PUT, DELETE) are the common request methods which allow us to do CRUD(Create Read Update Delete) operation. + +In the post, route we will use GET and POST method alternative depending on the type of request, check how it looks in the code below. The request method is a function to handle request methods and also to access form data. +app.py +```py +# let's import the flask +from flask import Flask, render_template, request, redirect, url_for +import os # importing operating system module + +app = Flask(__name__) +# to stop caching static file +app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0 + + + +@app.route('/') # this decorator create the home route +def home (): + techs = ['HTML', 'CSS', 'Flask', 'Python'] + name = '30 Days Of Python Programming' + return render_template('home.html', techs=techs, name = name, title = 'Home') + +@app.route('/about') +def about(): + name = '30 Days Of Python Programming' + return render_template('about.html', name = name, title = 'About Us') + +@app.route('/result') +def result(): + return render_template('result.html') + +@app.route('/post', methods= ['GET','POST']) +def post(): + name = 'Text Analyzer' + if request.method == 'GET': + return render_template('post.html', name = name, title = name) + if request.method =='POST': + content = request.form['content'] + print(content) + return redirect(url_for('result')) + +if __name__ == '__main__': + # for deployment + # to make it work for both production and development + port = int(os.environ.get("PORT", 5000)) + app.run(debug=True, host='0.0.0.0', port=port) +``` + So far, we have seen how to use template and how to inject data to template, how to a common layout. Now, lets handle static file. Create a folder called static in the project director and create a folder called css. Inside css folder create main.css. Your main. css file will be linked to the layout.html. @@ -1169,3 +1272,4 @@ After this step you will get an application like [this](https://thirtydaysofpyt --- +asabeneh@Asabeneh:~/Desktop/python_for_web$