Result not being displayed for machine learning prediction on the webpage - python

I am working on Malicious Webpage Detection using logistic regression and have used a dataset from kaggle. Using flask and html i want to predict whether the url is good or bad.
this is the code snippet in app.py
if request.method=='POST':
comment=request.form['comment']
X_predict1=[comment]
predict1 = vectorizer.transform(X_predict1)
New_predict1 = logit.predict(predict1)
new = New_predict1.tolist()
new1 = " ".join(str(x) for x in new)
return render_template('result.html',prediction=new1)
this code i have written in result.html
{% if prediction == 1%}
<h2 style="color:red;">Bad</h2>
{% elif prediction == 0%}
<h2 style="color:blue;">Good</h2>
{% endif %}
Why the results (Bad/Good) are not being displayed for this code?

I assume in app.py:
New_predict1.tolist() returns a list.
" ".join(str(x) for x in new) returns a concatenated string value.
In result.html:
prediction == 1 or prediction == 0 compares the value of prediction to integer. But from app.py you are sending a concatenated string value. So, this Bad or Good will not be shown in template.
You need to use String comparison like: prediction == "some constant"
I reproduced your scenario:
from flask import Flask, render_template, request
app = Flask(__name__)
#app.route('/', methods = ['GET', 'POST'])
def home():
if request.method == "POST":
comment=request.form.get('comment')
X_predict1=[comment]
# Do some operations
#predict1 = vectorizer.transform(X_predict1)
#New_predict1 = logit.predict(predict1)
#new = New_predict1.tolist()
#new1 = " ".join(str(x) for x in new)
# Dummy list
new = [1, 2, 3]
# " ".join() returns a string
new1 = " ".join(str(x) for x in new)
return render_template('result.html', prediction=new1)
return render_template('result.html')
if __name__ == "__main__":
app.run(debug=True)
result.html:
<html>
<head>
<title>Home</title>
</head>
<body>
<form action="/" method="post">
Comment:
<input type="text" name="comment"/>
<input type="submit" value="Submit">
</form>
<h3>Prediction Result</h3>
{% if prediction == 1 %}
<h2 style="color:red;">Bad</h2>
{% elif prediction == 0 %}
<h2 style="color:blue;">Good</h2>
{% else %}
<h2 style="color:black;">{{prediction}}</h2>
{% endif %}
</body>
</html>
Output:
As you can see the else block is triggered in the template as both if and elif block is skipped.

Related

Pokemon starter decision helper

I am fairly new to python/flask and would like to create a flask web-application that serves as a "personality test" which determines which of the original starter pokemon is the right for you based on the answers given.
There are 5 multiple choice questions.
I have declared global variables for every starter pokemon, that should be increased by 1 if the corresponding answer has been chosen.
After the 5th question this app should then display the right html file that simply tells the user which starter pokemon is the best fit for him/her. After submitting the fifth form, I always get the apology.html template, that should be rendered, when neither of the variables is bigger than the other two.
My instinct is that the variables do not properly get calculated, but I can't seem to figure out why.
I apologize if this seems very obvious, but I wasn't able to find anything like this in other questions asked and I am still very new to flask, with this being my first full application.
...
app = Flask(__name__)
app.config["TEMPLATES_AUTO_RELOAD"] = True
bs = 0 #global variable
sq = 0 #global variable
ch = 0 #global variable
#app.route("/question1/send", methods=["GET", "POST"])
def question1_send():
global bs, sq, ch
answer1 = request.form["answer1"]
if not answer1:
return apology("You have to choose an answer!", 403)
else:
if answer1 == "bs1":
bs += 1
elif answer1 == "sq1":
sq=sq+1
elif answer1 == "ch1":
ch=ch+1
return redirect("question2")
#app.route("/question1" ,methods=["GET", "POST"])
def question1():
if request.method == "GET":
return render_template("question1.html")
return redirect ("question1/send")
...
#app.route("/question5/send", methods=["GET", "POST"])
def question5_send():
global bs, sq, ch
answer5 = request.form["answer5"]
if not answer5:
return apology("You have to choose an answer!", 403)
else:
if answer5 == "bs5":
bs=bs+1
elif answer5 == "sq5":
sq=sq+1
elif answer5 == "ch5":
ch=ch+1
return redirect("/results")
#app.route("/question5" ,methods=["GET", "POST"])
def question5():
if request.method == "GET":
return render_template("question5.html")
return redirect ("question5/send")
#app.route("/results", methods=["GET", "POST"])
def starter_pokemon():
if ch > bs and ch > sq:
return render_template("charizard.html")
elif bs > ch and bs > sq:
return render_template("bulbasaur.html")
elif sq > ch and sq > bs:
return render_template("squirtle.html")
else:
return apology("Sorry something went wrong ", 403)
#app.errorhandler(404)
def not_found():
"""Page not found."""
return make_response(render_template("404.html"), 404)
if __name__ == "__main__":
flaskapp.run()
Here is the question5.html file that. It has radio buttons to choose an answer.
When you click the submit button it should redirect to /results which then renders the correct template showing which starter had the most answers chosen.
Maybe request.form.get("...") also does not retrieve the correct data
...
{% block main %}
<form id="question5" action="/question5/send" method="POST">
<h2>Which of these jobs would be your favourite</h2>
<br>
<input type="radio" name="answer5" id="a5_bulbasaur" value="bs5">
<label for="a5_bulbasaur">Gardener</label>
<br>
<input type="radio" name="answer5" id="a5_squirtle" value="sq5">
<label for="a5_squirtle">Firefighter</label>
<br>
<input type="radio" name="answer5" id="a5_charmander" value="ch5">
<label for="a5_charmander">fire breather</label>
<br>
<button type="submit" name="b5">Next Question</button>
</form>
{% endblock %}
This is one of the templates that "/results" should render:
{% extends "layout.html" %}
{% block title %}
Bulbasaur
{% endblock %}
{% block main %}
<h1>It seems like bulbasaur is the perfect partner for you!</h1>
<br>
<img src="https://assets.pokemon.com/assets/cms2/img/pokedex/full/001.png" alt="bulbasaur" width="" height="600">
<br>
<h2>You are a nature loving person, who cares about the people and animals around you that tries to find the balance in everything you do.</h2>
{% endblock %}
Like I said I hope this question is not too obvious that it makes it embarrassing to ask.
But I am stuck at this for 2 days and can't seem to figure it out by myself by reading flasks documentation.
Thanks in advance :)

Why is my form trying to submit to the wrong endpoint?

I have a python script and a mongoDB instance.
With flask I now want to list all the items of my database on a webpage and use a second webpage to trigger the script to add an other item.
But everytime I click "submit" on the "/add" page, I get a "Method not allowed" and I can see, that it tries to submit it to "/" instead of "/add" ..
script.py
from flask import Flask, render_template, request
import requests, json, sys, getopt, smtplib
from os import system, name
from pathlib import Path
from pymongo import MongoClient
client = MongoClient(port = 27017)
db = client.amazonProducts
allitems = []
allMyItems = []
for document in db.items.find():
allitems.append(document["name"])
def addItem():
for dbWishList in db.wishlist.find():
url = dbWishList["wishlist"]
items = json.loads(requests.get(url).text)
if items:
for item in items:
itemName = str(item["name"])
itemPrice = item["new-price"]
itemUrl = str(item['link'])
if itemPrice:
itemPrice = str(itemPrice[26: ])
itemPrice = str(itemPrice[: itemPrice.find("<")])
itemPriceF = str(itemPrice.replace(".", ""))
itemPriceF = str(itemPriceF.replace("€", ""))
itemPriceF = str(itemPriceF.replace("\xa0", ""))
itemPriceF = str(itemPriceF.replace(",", ".")).replace("\xf6", "")
itemPriceFi = float(itemPriceF)
itemUrl = itemUrl[: itemUrl.find("?coliid")]
itemNameF = itemName.replace('"', '"')
itemNameFi = itemNameF.replace("&amp;", "&")
itemNameFi = itemNameFi.replace("ü", "ue").replace("ö", "oe").replace("ä", "ae").replace(" ", " ").replace("–", "-")
amazonItem = {
'name': itemNameFi,
'url': itemUrl,
'price': itemPriceFi,
'maxPrice': 0
}
db.items.insert_one(amazonItem)
for document in db.items.find():
allMyItems.append(document["name"])
return allMyItems
app = Flask(__name__)
#app.route('/')
def homepage():
return render_template("index.html", len = len(allitems), allitems = allitems)
app.run(use_reloader = True, debug = True)
app.config["DEBUG"] = True
#app.route("/add", methods = ["GET", "POST"])
def secPage():
errors = ""
if request.method == "POST":
global testingVar
testingVar = None
try:
testingVar = string(request.form["testingVar"])
except:
errors += "<p>{!r} is not a string.</p>\n".format(request.form["testingVar"])
if testingVar is not None:
addItem()
return render_template("secIndex.html", len = len(allMyItems), allMyItems = allMyItems)
return '''
<html>
<body>
{errors}
<p>What you wanna do?:</p>
<form method="post" action=".">
<p><input name="testingVar" /></p>
<p><input type="submit" value="Do magic" /></p>
</form>
</body>
</html>
'''.format(errors=errors)
index.html
<!DOCTYPE html>
<html>
<head>
<title>For loop in Flask</title>
</head>
<body>
<ul>
<!-- For loop logic of jinja template -->
{%for i in range(0, len)%}
<li>{{allitems[i]}}</li>
{%endfor%}
</ul>
</body>
</html>
secIndex.html
<!DOCTYPE html>
<html>
<head>
<title>For loop in Flask</title>
</head>
<body>
<!-- For loop logic of jinja template -->
<form method="post" action=".">
<p><input name="testingVar" /></p>
<p><input type="submit" value="Do magic" /></p>
</form>
</body>
</html>
The items are built like:
amazonItem = {
'name': itemNameFi,
'url': itemUrl,
'price': itemPriceFi,
'maxPrice': 0
}
Can anyone here follow me and tell me where my mistake might be?
In your form definition you have:
<form method="post" action=".">
The action attribute needs to have the endpoint you want to send the post request to. In your case, you want
<form method="post" action="/add">
If you omit the action attribute, it will submit the post request to the current page, so if you are viewing your form from /add, you can just use
<form method="post">

Flask - how to keep list index after form submit?

I have a list of images that I want to display on a page. These image names are formatted basically YYYYMMDD_HHMMSS.jpg. I want this single page to either list all images, or only list and show those taken on a certain date (meaning a main page, not like /index to show all images, /date-specific to show some images).
So far, I have been able to show all images, and click "next"/"previous" buttons to loop through all images. I also have a table below the image, showing all the images that are in the index.
Works great - no issues.
However, I am also trying to implement a date filter, where the user can select a date from the Calendar Picker, and have the site filter out and only show photos on that day. So far, I can successfully filter one time. However, when I click "next"/"previous" buttons, or choose an image from the table, it resets back to the full list of images.
How do I keep the filtered list? I thought I could do it by keeping the date chosen in the Input field, but after using the "next"/"previous" buttons, the whole page resets and it clears that field.
I also tried including the list in the HTML portion, but it still returns all the photos. (Also makes the URL ugly, since it includes the image list for each photo listed in the table):
<td> {{ image }} </td>
Here's a .gif of the page I'm working on.. First, you'll see I can successfully click around, navigate between all photos. Then, I can successfully filter to show photos on a specific date. However, anything past that keeps sending me back to the full image list.
Anyways, without further ado, here's the codes. (Note I try to keep it minimal, so might have omitted an important piece, so please let me know if I need to post something else here):
routes.py
import os
import random
from flask import render_template, url_for, request, Blueprint, redirect # noqa
from app import app
IMAGE_FOLDER = r"C:/MyPath/Test"
FAVORITE_LIST = os.path.join(IMAGE_FOLDER, "favorites.txt")
blueprint = Blueprint('images', __name__,
static_url_path='/static/images',
static_folder=IMAGE_FOLDER)
app.register_blueprint(blueprint)
images = os.listdir(IMAGE_FOLDER)
image_urls = ["20190411_123200.jpg", ... other images in a list]
class Photo_Index():
def __init__(self, index=0):
self.index = index
def increase_number(self, num_images):
if self.index == num_images:
self.index = 0
else:
self.index = self.index + 1
return self.index
def decrease_number(self, num_images):
if self.index == 0:
self.index = num_images
else:
self.index = self.index - 1
return self.index
def random_number(self, num_images):
self.index = random.randint(0, num_images)
return self.index
def set_number(self, number):
self.index = number
return self.index
# functions to create and edit Favorites. this works so I'm excluding]
def day_month_year(filename):
"""
Takes a string `20190212` and pulls out Year, Month, Date
"""
year = filename[:4]
month = filename[4:6]
day = filename[6:8]
return str(year + "-" + month + "-" + day)
def get_files_on(specific_date):
_files = []
print("\nLooking for files on:", specific_date, "\n")
for file in image_urls:
# print(file, day_month_year(file))
if day_month_year(file) == specific_date:
_files.append(file)
return _files
photo_index_obj = Photo_Index()
fav_photo_index = Photo_Index()
def update_index(rqst, indx_obj, num_images):
print("Updating index, have", num_images, "photos")
if num_images == 1:
indx_obj.set_number(0)
elif 'prev-photo' in rqst.form:
indx_obj.decrease_number(num_images)
elif 'next-photo' in rqst.form:
indx_obj.increase_number(num_images)
elif 'random-photo' in rqst.form:
indx_obj.random_number(num_images)
return indx_obj
#app.route("/<chosen_image>", methods=["GET", "POST"])
#app.route("/", methods=["GET", "POST"])
def default_template(date=None, image_list=None, chosen_image=None):
if image_list is None:
image_list = image_urls
num_images = len(image_list) - 1
if request.method == "POST":
if 'go-to-date' in request.form:
date = request.form['go-to-date']
image_list = get_files_on(date)
num_images = len(image_list) - 1
photo_index_obj.set_number(0)
if len(image_list) == 0:
image_list = ["no_images_for_date.jpg"]
elif 'prev-next-buttons' in request.form:
print("Updating index, have", num_images, "photos")
update_index(request, photo_index_obj, num_images)
elif 'favorite-photo' in request.form:
add_to_favorites(image_list[photo_index_obj.index])
elif 'un-favorite-photo' in request.form:
remove_from_favorites(image_list[photo_index_obj.index])
if chosen_image is None:
chosen_image = image_list[photo_index_obj.index]
elif chosen_image is not None:
photo_index_obj.set_number(image_list.index(chosen_image))
favorite = is_favorite(image_list[photo_index_obj.index])
print("Images:", image_list)
return render_template('index.html',
title="Local Image Viewer",
photo_index=photo_index_obj.index,
image=chosen_image,
image_list=image_list,
favorite=favorite)
#app.route("/<chosen_image>", methods=["GET", "POST"])
def chosen_image(chosen_image):
date = request.form['go-to-date']
return default_template(date=date,
chosen_image=chosen_image)
index.html (I omitted the Select list, as that's kind of superfluous for this post)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>{{ title }}</title>
<link rel="stylesheet" type="text/css" href= "{{ url_for('static',filename='styles/index.css') }}">
<link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}">
</head>
<body>
{% extends "layout.html" %}
{% block content %}
<h3>Index: {{ photo_index }}</h3>
<h3>Filename: {{ image }}</h3>
<div id="calendar-selector">
{% include "/HTML Snippets/calendar.html" %}
</div>
<div class='image-container' id='image'>
{% include "/HTML Snippets/favorite_button.html" %}
<img src="{{ url_for('images.static', filename=image) }} " id="the-photo">
</div>
<div class='button-container' id='buttons'>
<form action="" method="post">
<input type="hidden" name="prev-next-buttons">
<input type="submit" value="Prev photo" name='prev-photo'>
<input type="submit" value="Next photo" name='next-photo'>
<input type="submit" value="Random photo" name='random-photo'>
<br/>
<button type='button' id='rotate-button' onclick="rotateMeCounterClockwise('#the-photo')">Rotate Photo CounterClockwise</button>
<button type='button' id='rotate-button' onclick="rotateMeClockwise('#the-photo')">Rotate Photo Clockwise</button>
</form>
</div>
<div class='table-container'>
<table id='image-list' name='select-from-table'>
{% for image_row in image_list | batch(3) %}
<tr>
{% for image in image_row %}
<td> {{ image }} </td>
{% endfor %}
</tr>
{% endfor %}
</table>
</div>
{% endblock %}
</body>
</html>
and the calendar bit, calendar.html
{% block topscripts %}
<link rel="stylesheet" type="text/css" href= "{{ url_for('static',filename='styles/calendar.css') }}">
<script>
$(function() {
$("#datepicker").datepicker({dateFormat: 'yy-mm-dd'});
});
</script>
{% endblock %}
{% block content %}
<form method="post" action="{{ url_for('default_template') }}">
<input type="hidden" name="calendar-form">
<p>
Date: <input type="text" id="datepicker" name='go-to-date'
{% if request.form['go-to-date'] is not none %}
value="{{request.form['go-to-date']}}"
{% endif %}
></p>
<input type="submit">
</form>
{% endblock %}
{% block endscripts %}
{% endblock %}
You need to pass along enough information in your next/previous form and in the table links to re-apply the date filter. Your calendar form is separate from the next/previous navigation form, the browser won't serialise information from one when submitting the other. Clicks on <a href="..."> links will not include the date input field value either.
Note that clicks on the table links generate GET requests, so you need to look for go-to-date in the request.values mapping to accommodate both query parameters and form data.
You need to look for this parameter not only when you receive a POST request, but for all requests:
if 'go-to-date' in request.values:
date = request.values['go-to-date']
image_list = get_files_on(date)
photo_index_obj.set_number(0)
if len(image_list) == 0:
image_list = ["no_images_for_date.jpg"]
else:
image_list = image_list or image_urls
num_images = len(image_list) - 1
if request.method == 'POST':
# ...
Then generate URLs that include the parameter:
{%- set url_params = {'go-to-date': request.values['go-to-date']} if request.values['go-to-date'] else {} -%}
{% for image in image_row %}
<td> {{ image }} </td>
{% endfor %}
For the next/previous form, just add a hidden input field with the current go-to-date value:
<form action="" method="post">
<input type="hidden" name="prev-next-buttons">
{%- if request.values['go-to-date'] -%}
<input type="hidden" name="go-to-date" value="{{ request.values['go-to-date'] }}">
{%- endif -%}
<input type="submit" value="Prev photo" name='prev-photo'>
<input type="submit" value="Next photo" name='next-photo'>
<input type="submit" value="Random photo" name='random-photo'>
<br/>
<button type='button' id='rotate-button' onclick="rotateMeCounterClockwise('#the-photo')">Rotate Photo CounterClockwise</button>
<button type='button' id='rotate-button' onclick="rotateMeClockwise('#the-photo')">Rotate Photo Clockwise</button>
</form>

how can i use a variable from my view on a if statement in django

Im trying to change a boolean value in django when I click an input image I think I already done it but now when I try to compare this boolean in my html it doesnt bring the correct value it always brings its as False (sn6.jpg)
View.py
def reservacion(request):
if request.method == "POST":
estatus = Asientos.objects.get(asiento=1)
if estatus.status == True:
estatus.status = False
estatus.save()
else:
estatus.status = True
estatus.save()
return render(request,"reservacion.html")
Models.py
class Reserva(models.Model):
mesa = models.CharField(max_length=2,primary_key=True)
asiento = models.ForeignKey(Asientos)
def __str__(self):
return self.mesa
html-- in here my if statements change the value of the boolean on my DB but it always shows the image in False (sn6.jpg)
<form enctype="multipart/form-data" method="post">
{% csrf_token %}
<div class="row">
{% if estatus.status == True%}
<div class="col"><input class="d-block w-100" type="image" src="{%static "/img/s6.jpg" %}" name="1" value=""></div>
{% else %}
<div class="col"><input class="d-block w-100" type="image" src="{%static "/img/sn6.jpg" %}" name="1" value=""></div>
{% endif %}
</form>
Am I missing something?, how can i get the other oimage when i click and submit the value?
Two points:
you need to add a context dictionary to your render to pass variable to your template : render(request,"reservacion.html", {‘estatus’: estatus})
and no need to compare a Boolean to True, this is enough : if estatus.status

Why doesn't this loop run?

As you can see, this code lets the user create models called Images. The problem is, no images are actually created when I want them to be. The print test with the obnoxious caps (print images) returns an empty list after I've inputted information multiple times.
Perhaps related to this issue, I simply cannot add print tests to any of the if/else loops in the code. It returns an indentation error, even when I check all of the indents for four spaces.
I'm really confused. I suspect I'm misunderstanding the control flow?
views.py:
from django.shortcuts import render
from images_app.models import Image
def index(request):
images = Image.objects.all()
image_names = [a.name for a in images]
print images ### THIS RETURNS AN EMPTY LIST!!
if request.method == 'POST':
image_string = request.POST.get('get_image')
index = image_string.find('(')
# divide input into parent and child
if index == -1:
parent = image_string
child = None
else:
parent = image_string[0:index]
child = image_string[index+1:len(image_string)-1]
# print "Child is.. ", child.name ### THIS RETURNS AN INDENTATION ERROR
# create models based on input
if parent not in image_names and child not in image_names:
parent_model = Image(name=parent)
child_model = Image(name=child, parent=parent_model)
elif parent in image_names and child not in image_names:
parent_model = images.get(name=parent)
child_model = Image(name=child, parent=parent_model)
elif parent not in image_names and child in image_names:
child_model = images.get(name=child)
parent_model = Image(name=parent)
child_model.parent = parent_model
print "descendants are: ", parent_model.get_descendants()
else:
print "else"
return render(request, 'images_app/index.html', {'images':images})
def get_images(request):
term = request.GET.get('terms') #jquery-ui.autocomplete parameter
images = Image.objects.filter(name__istartswith=terms)
res = []
for i in images:
#make dict with the metadatas that jquery-ui.autocomple needs
dict = {'id':i.id, 'label':i.__unicode__(), 'value':i.__unicode__()}
res.append(dict)
return HttpResponse(simplejson.dumps(res))
index.html:
<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<title> images </title>
<script>
<script type="text/javascript">
$(function() {
$("#terms").autocomplete({
source: "{% url 'images_app:get_images' %}",
minLength: 1,
});
});
</script>
</head>
<nav>
associate
</nav>
<body>
{% for images in images %}
{{ image.name }}
{% endfor %}
<section>
<h1>create an image</h1>
<form action="{% url 'images_app:index' %}" method="post">
{% csrf_token %}
<div class="ui-widget">
<label for="get_image">create image: </label>
<input id="get_image" name="get_image">
</div>
<div id="buttons">
<input type="submit" value="create" class="submit" name="create" />
</div>
</form>
</section>
</body>
You don't ever save any of your images.
Doing Image(blah) simply instantiates an object in memory. You need to call .save() on the instance, or alternatively do Image.objects.create(blah) to instantiate and save at the same time.

Categories

Resources