Add exercises 26
Signed-off-by: Manuel Vergara <manuel@vergaracarmona.es>
This commit is contained in:
parent
d8426a91d9
commit
08d20fee61
@ -6,4 +6,6 @@ Documento original en inglés: [Python web](https://github.com/Asabeneh/30-Days-
|
|||||||
|
|
||||||
1. Construirás esta [aplicación](https://thirtydaysofpython-v1-final.herokuapp.com/). Solo queda la parte del analizador de texto.
|
1. Construirás esta [aplicación](https://thirtydaysofpython-v1-final.herokuapp.com/). Solo queda la parte del analizador de texto.
|
||||||
|
|
||||||
|
[Solución](./web/)
|
||||||
|
|
||||||
[<< Day 25](../25_Pandas/README.md) | [Day 27 >>](../27_Python_con_MongoDB/README.md)
|
[<< Day 25](../25_Pandas/README.md) | [Day 27 >>](../27_Python_con_MongoDB/README.md)
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
web: python app.py
|
44
30-days-of-python/26_Desarrollo_web_en_Python/web/app.py
Normal file
44
30-days-of-python/26_Desarrollo_web_en_Python/web/app.py
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
"""
|
||||||
|
app.py
|
||||||
|
"""
|
||||||
|
|
||||||
|
from flask import Flask, render_template, request, redirect, url_for
|
||||||
|
import os
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0
|
||||||
|
|
||||||
|
|
||||||
|
@app.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__':
|
||||||
|
port = int(os.environ.get("PORT", 5000))
|
||||||
|
app.run(debug=True, host='0.0.0.0', port=port)
|
@ -0,0 +1,7 @@
|
|||||||
|
blinker==1.6.3
|
||||||
|
click==8.1.7
|
||||||
|
Flask==3.0.0
|
||||||
|
itsdangerous==2.1.2
|
||||||
|
Jinja2==3.1.2
|
||||||
|
MarkupSafe==2.1.3
|
||||||
|
Werkzeug==3.0.0
|
@ -0,0 +1,206 @@
|
|||||||
|
/* === GENERAL === */
|
||||||
|
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* === css variables === */
|
||||||
|
:root {
|
||||||
|
--header-bg-color: #4a7799;
|
||||||
|
--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.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: 20px;
|
||||||
|
font-weight: 300;
|
||||||
|
font-family: Nunito;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* === header menu style === */
|
||||||
|
|
||||||
|
.menu-container {
|
||||||
|
width: 90%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
align-items: center;
|
||||||
|
color: rgb(221, 215, 215);
|
||||||
|
padding: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-lists {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-list {
|
||||||
|
list-style: none;
|
||||||
|
margin: 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-link {
|
||||||
|
text-decoration: none;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* === 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;
|
||||||
|
border: 1px solid var(--header-bg-color);
|
||||||
|
font-family: Lato;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:focus {
|
||||||
|
outline: 2px solid #2a70a5;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* === textarea style === */
|
||||||
|
textarea {
|
||||||
|
width: 65%;
|
||||||
|
margin: auto;
|
||||||
|
padding: 15px;
|
||||||
|
outline: 2px solid rgba(207, 203, 203, 0.25);
|
||||||
|
border: none;
|
||||||
|
font-size: 18px;
|
||||||
|
font-family: Lato;
|
||||||
|
font-weight: 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-header {
|
||||||
|
font-weight: 300;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea:focus {
|
||||||
|
border: none;
|
||||||
|
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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
width: 50%;
|
||||||
|
text-align: center;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr {
|
||||||
|
background-color: #f8f8f8;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
padding: .35em;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody tr,
|
||||||
|
tbody td {
|
||||||
|
padding: .625em;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
thead tr th {
|
||||||
|
background: var(--header-bg-color);
|
||||||
|
font-size: .85em;
|
||||||
|
letter-spacing: .1em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
padding: 15px;
|
||||||
|
color: var(--nav-link-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* === responsiveness === */
|
||||||
|
@media (max-width:600px) {
|
||||||
|
main {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-container {
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-lists {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
{% extends 'layout.html' %} {% block content %}
|
||||||
|
<div class="container">
|
||||||
|
<h1>Sobre esto</h1>
|
||||||
|
<iframe src="https://giphy.com/embed/eH9sawQbajAQM" width="480" height="120"
|
||||||
|
frameBorder="0" class="giphy-embed" allowFullScreen></iframe>
|
||||||
|
<p>
|
||||||
|
Poco que decir, solo que esto es una web hecha con python y flask.
|
||||||
|
Es un ejercicio que se ha extraído del <a
|
||||||
|
href="https://github.com/Asabeneh/30-Days-Of-Python"> repositorio
|
||||||
|
github de 30DaysOfPython</a>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
@ -0,0 +1,23 @@
|
|||||||
|
{% extends 'layout.html' %} {% block content %}
|
||||||
|
<div class="container">
|
||||||
|
<h1>Welcome to {{name}}</h1>
|
||||||
|
<div>
|
||||||
|
<img src="https://c.tenor.com/Zdpc10JrZrIAAAAC/tenor.gif"
|
||||||
|
alt="python" />
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
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:
|
||||||
|
</p>
|
||||||
|
<ul class="tech-lists">
|
||||||
|
{% for tech in techs %}
|
||||||
|
<li class="tech">{{tech}}</li>
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
@ -0,0 +1,43 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<link
|
||||||
|
href="https://fonts.googleapis.com/css?family=Lato:300,400|Nunito:300,400|Raleway:300,400,500&display=swap"
|
||||||
|
rel="stylesheet" />
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="{{ url_for('static', filename='css/main.css') }}" />
|
||||||
|
{% if title %}
|
||||||
|
<title>30 Days of Python - {{ title}}</title>
|
||||||
|
{% else %}
|
||||||
|
<title>30 Days of Python</title>
|
||||||
|
{% endif %}
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<header>
|
||||||
|
<div class="menu-container">
|
||||||
|
<div>
|
||||||
|
<a class="brand-name nav-link" href="/">30DaysOfPython</a>
|
||||||
|
</div>
|
||||||
|
<ul class="nav-lists">
|
||||||
|
<li class="nav-list">
|
||||||
|
<a class="nav-link active" href="{{ url_for('home') }}">Home</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-list">
|
||||||
|
<a class="nav-link active" href="{{ url_for('about') }}">About</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-list">
|
||||||
|
<a class="nav-link active" href="{{ url_for('post') }}">Text
|
||||||
|
Analyzer</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<main>
|
||||||
|
{% block content %} {% endblock %}
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,15 @@
|
|||||||
|
{% extends 'layout.html' %} {% block content %}
|
||||||
|
<div class="container">
|
||||||
|
<h1>Text Analyzer</h1>
|
||||||
|
<form action="localhost:5000/post"
|
||||||
|
method="POST">
|
||||||
|
<div>
|
||||||
|
<textarea rows="25" name="content" autofocus></textarea>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<input type="submit" class="btn" value="Process Text" />
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
Loading…
Reference in New Issue
Block a user