2

I want to use input from html to be a function in my Flask:

from flask import Flask, url_for, render_template from flask_wtf import FlaskForm from wtforms import StringField, SubmitField from wtforms.validators import DataRequired app = Flask(__name__) @app.route("/") def homepage() : return render_template("index.html", make_cards = make_cards(user_deck), make_cards_u = user_cards(), result = find_winner(user_deck, computer_deck)) class user_cards (FlaskForm): SUITS = StringField('suits', validators=[DataRequired()]) SEQUENCE = StringField('stringfield', validators=[DataRequired()]) submit = SubmitField('Check!') if __name__ == '__main__': # print(poker_hand_ranking(["10H", "JH", "QH", "AH", "KH"])) user_deck = user_cards() computer_deck = make_cards(user_deck) find_winner(user_deck, computer_deck) app.run(debug=True) 

I want this program to interact with the user, so I did not define make_cards_u, and want an user input for the cards. So my HTML is as follows:

<!DOCTYPE html> <html> <head> <meta charset="UTF=8"> <title> Poker Game </title> <link rel="stylesheet" href ="{{url_for('static', filename='css/style.css')}}"> </head> <body> <h1> Welcome to Gaming Poker</h1> <h3>Computer cards: {{make_cards}} <br> Your cards: <input> {{make_cards_u}} </input> </h3> <h2>Results: {{result}}</h2> </body> </html> 

However, I am getting an error

RuntimeError: Working outside of application context. This typically means that you attempted to use functionality that needed to interface with the current application object in some way. To solve this, set up an application context with app.app_context(). See the documentation for more information. 

My other python codes are as follow:

SEQUENCE = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A'] VALUES = {'2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9, '10': 10, 'J': 11, 'Q': 12, 'K': 13, 'A': 14} SUITS = ['S', 'H', 'C', 'D'] # The computer gets 5 cards def make_cards(deck = None): result_deck = set() while (len(result_deck) < 5): card = random.choice(SEQUENCE) + random.choice(SUITS) if (deck != None): if (card not in deck): result_deck.add(card) else: result_deck.add(card) return list(result_deck) def find_winner(user_deck, computer_deck): user_rank = poker_hand_ranking(user_deck) computer_rank = poker_hand_ranking(computer_deck) if (user_rank[0] < computer_rank[0]): print('Winner is user') elif (user_rank[0] > computer_rank[0]): print('Winner is computer') else: print('Draw!') print('User:', user_deck, user_rank[1]) print('Computer:', computer_deck, computer_rank[1]) 

Also, I have codes that defines variables inside the if elif statements, which was too long to put in this question. The poker_hand_ranking was defined as below:

def poker_hand_ranking(deck): hand = deck suits = sorted([card[-1] for card in hand]) faces = sorted([card[:-1] for card in hand]) if is_royal_flush(hand, suits, faces): return 1, "You have a Royal Flush" elif is_straight_flush(hand, suits, faces): return 2, "You have a Straight Flush" elif is_four_of_a_kind(hand, suits, faces): return 3, "You have four of a Kind" elif is_full_house(hand, suits, faces): return 4, "You have a full House" elif is_flush(hand, suits, faces): return 5, "You have a flush" elif is_straight(hand, suits, faces): return 6, "You have a straight" elif is_three_of_a_kind(hand, suits, faces): return 7, "You have a three of a Kind" elif is_two_pairs(hand, suits, faces): return 8, "You have a two Pair" elif is_one_pair(hand, suits, faces): return 9, "You have a pair" else: #if none of these counts: return 10, "High Card" 

How do I make the user input interact in Flask?

2
  • 1
    include make_cards and find_winner method in the question. Commented Jul 18, 2020 at 16:05
  • @arsho thank you, I have done so! Commented Jul 18, 2020 at 16:11

1 Answer 1

1

You could use the form user_cards in the template to create a HTML form and then handle the submitted value in the flask code.

You can check the user submitted values with your generated card decks and then decide who wins the game.

Here is my approach. As I do not have all the logic of poker game, I have randomly returned the poker hand ranking. You can replace it with original method.

Directory structure:

. ├── requirements.txt ├── sample_form.py └── templates └── index.html 

requirements.txt:

click==7.1.2 Flask==1.1.2 Flask-WTF==0.14.3 itsdangerous==1.1.0 Jinja2==2.11.2 MarkupSafe==1.1.1 Werkzeug==1.0.1 WTForms==2.3.1 

sample_form.py:

import random from flask import Flask, url_for, render_template from flask_wtf import FlaskForm from wtforms import StringField, SubmitField from wtforms.validators import DataRequired app = Flask(__name__) # Set the secret key to some random bytes. Keep this really secret! app.secret_key = b'_5#y2L"F4Q8z\n\xec]/' SEQUENCE = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A'] VALUES = {'2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9, '10': 10, 'J': 11, 'Q': 12, 'K': 13, 'A': 14} SUITS = ['S', 'H', 'C', 'D'] # The computer gets 5 cards def make_cards(deck = None): result_deck = set() while len(result_deck) < 5: card = random.choice(SEQUENCE) + random.choice(SUITS) if deck != None: if card not in deck: result_deck.add(card) else: result_deck.add(card) return list(result_deck) def find_winner(user_deck, computer_deck): user_rank = poker_hand_ranking(user_deck) computer_rank = poker_hand_ranking(computer_deck) if user_rank[0] < computer_rank[0]: return 'Winner is user' elif user_rank[0] > computer_rank[0]: return 'Winner is computer' else: return 'Draw!' def poker_hand_ranking(deck): return random.choice(["some", "many"]) class user_cards(FlaskForm): suits = StringField('suits', validators=[DataRequired()]) sequence = StringField('sequence', validators=[DataRequired()]) submit = SubmitField('Check!') @app.route("/", methods=['GET', 'POST']) def homepage(): card_form = user_cards() if card_form.validate_on_submit(): user_deck = ["{}{}".format(card_form.suits.data, card_form.sequence.data)] computer_deck = make_cards() result = find_winner(user_cards, computer_deck) return render_template('index.html', form=card_form, user_deck=user_deck, computer_deck=computer_deck, result=result) return render_template('index.html', form=card_form) 

templates/index.html:

<html> <head> <title> Card Form </title> </head> <body> <h1> Welcome to Gaming Poker</h1> <h2>Input Cards</h2> <form method="POST" action="/"> {{ form.csrf_token }} {{ form.suits.label }} {{ form.suits(size=20) }} {{ form.sequence.label }} {{ form.sequence(size=20) }} {{ form.submit }} </form> {% if computer_deck %} <h3>Computer cards: {{computer_deck}} </h3> {% endif %} {% if user_deck %} <h3>Your cards: {{user_deck}}</h3> {% endif %} {% if result %} <h2>Results: {{result}}</h2> {% endif %} </body> </html> 

Output:

Before form submission:

before form submission

After form submission:

after submission

Disclaimer:

I have not actually selected the correct winner. Please include your logic. Hopefully my snippets will help you to understand how to work with form in Flask using Flask-wtf package.

Reference:

Sign up to request clarification or add additional context in comments.

8 Comments

a problem called "Instance of 'user_cards' has no 'data' member pylint(no-member) is occurring when I tried it
I think, this is a warning on the pylint. You need to install the required packages. After submission of the form user_cards has data attribute which contains the form data.
sorry for a dumb question, but I am learning by myself. What packages do I need to install?
I have updated the portion of code. Try current flask code. I think you have already installed the required package. If not, install the packages mentioned in requirements.txt.
Have you tried my snippets as it is? I would suggest to run my code at first. Then try to insert your logic. In your code, you are doing operation in __main__ block which may arose the above error.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.