CS50 - Jinja formatting in HTML

Viewed 21

I'm having trouble with the formatting of my jinja for loop. It's a name generator that generates a first and last name. I am combining the first and last name in my code but when it outputs to the HTML file its not formatted and has brackets. I'm not really sure where to modify it and this is probably something simple I'm missing. Your help would be greatly appreciated. Thank you!

Python Code

from cs50 import SQL
from flask import Flask, render_template, render_template_string, request
from tempfile import mkdtemp
import random

# Configure application
app = Flask(__name__)

# Ensure templates are auto-reloaded
app.config["TEMPLATES_AUTO_RELOAD"] = True

# Configure CS50 Library to use SQLite database
db = SQL("sqlite:///names.db")



@app.route("/")
def index():
    return render_template("index.html")

@app.route("/results", methods=["POST"])
def results():
    gender = request.form.get("gender")
    number_results = int(request.form.get("number_results"))

    results = []

    for i in range(number_results):
        if gender == "male":
            random_id_male = random.randint(1, 1000)
            random_id_last = random.randint(1, 1000)
            male_name = db.execute("SELECT name FROM male_names WHERE id = ?", random_id_male)
            last_name = db.execute("SELECT name FROM last_names WHERE id = ?", random_id_last)
            total_male = male_name + last_name
            results.append(total_male)
        elif gender == "female":
            random_id_female = random.randint(1, 1000)
            random_id_last = random.randint(1, 1000)
            female_name = db.execute("SELECT name FROM female_names WHERE id = ?", random_id_female)
            last_name = db.execute("SELECT name FROM last_names WHERE id = ?", random_id_last)
            total_female = female_name + last_name
            results.append(total_female)
        elif gender == "other":
            random_id_other = random.randint(1, 300)
            random_id_last = random.randint(1, 1000)
            other_name = db.execute("SELECT name FROM other_names WHERE id = ?", random_id_other)
            last_name = db.execute("SELECT name FROM last_names WHERE id = ?", random_id_last)
            total_other = other_name + last_name
            results.append(total_other)

    return render_template("index.html", results=results)

HTML for index

<head>

  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1, width=device-width">

  <!-- http://getbootstrap.com/docs/5.1/ -->
  <link crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" rel="stylesheet">
  <script crossorigin="anonymous" src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p"></script>

  <link href="/static/styles.css" rel="stylesheet">

  <title>Fantasy Name Generator</title>

</head>
<header>
  <!-- Background image -->
  <div class="p-5 text-center bg-image" style="background-image: url('https://images.pexels.com/photos/326055/pexels-photo-326055.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1'); height: 400px;">
    <div class="mask" style="background-color: rgba(0, 0, 0, 0.6);">
      <div class="d-flex justify-content-center align-items-center h-100">
        <div class="text-white">
          <h1 class="mb-3">Fantasy Name Generator</h1>
        </div>
      </div>
    </div>
  </div>
  <!-- Background image -->
</header>
<body>
  <!--Form to get data from user-->
  <form action="/results" method="post">
      <!--radio buttons to choose gender-->
      <div class="form-check form-check-inline">
        <input class="form-check-input" type="radio" name="gender" id="inlineRadio1" value="male">
        <label class="form-check-label" for="inlineRadio1">Male</label>
      </div>
      <div class="form-check form-check-inline">
        <input class="form-check-input" type="radio" name="gender" id="inlineRadio2" value="female">
        <label class="form-check-label" for="inlineRadio2">Female</label>
      </div>
      <div class="form-check form-check-inline">
        <input class="form-check-input" type="radio" name="gender" id="inlineRadio3" value="other">
        <label class="form-check-label" for="inlineRadio3">Neutral</label>
      </div>
      <div class="flex flex-col items-center">
        <label class="pb-1" for="number_results">results</label>
        <select name="number_results" id="number_results" required class="mb-4 rounded-md">
            <option value="10" selected>10</option>
            <option value="20">20</option>
            <option value="30">30</option>
            <option value="40">40</option>
            <option value="50">50</option>
        </select>
    </div>
    <button class="btn btn-primary" type="submit">Generate Names</button>
  </form>
      <!-- Names get generated here -->
      <div id="results" class="transition flex flex-col pt-6 md:pt-8" >
        <ul aria-label="results" class="m-auto text-center font-medium tracking-wide column-count-1 sm:column-count-3 lg:column-count-5">
        {% for result in results %}
            <ul class="">{{ result }}</ul>
        {% endfor %}
        </ul>
      </div>
  </body>

What the output looks like on the index.html page

[{'name': 'Oswaldo'}, {'name': 'Navarro'}]
[{'name': 'Jamir'}, {'name': 'Wagner'}]
[{'name': 'Rodrigo'}, {'name': 'Valenzuela'}]
[{'name': 'Davion'}, {'name': 'Molina'}]
[{'name': 'Zechariah'}, {'name': 'Austin'}]
[{'name': 'Jace'}, {'name': 'Conner'}]
[{'name': 'Valentino'}, {'name': 'Zavala'}]
[{'name': 'Kadin'}, {'name': 'Leblanc'}]
[{'name': 'Emmanuel'}, {'name': 'Mccann'}]
[{'name': 'Alexander'}, {'name': 'Erickson'}]
1 Answers

cs50 execute method returns a list of dictionaries. list + list (as in total_other = other_name + last_name) returns one list with all the elements from both lists. append is appending a list. Therefore results is a list of lists, each list contains 2 dictionaries. One way to resolve this is to transform total_{genders} to strings, not a list of dictionaries, then append to results.

Each execute90 returns a list with exactly one dictionary element and each dictionary has exactly one key ('name'), so the data would be addressed as row[0]['name']. It is then elementary to build a string for each (2 part) name and append to the results list.

Related