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.
|
||||
|
||||
[Solución](./web/)
|
||||
|
||||
[<< 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