Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python

William Watlington
William Watlington
3,347 Points

Problem understanding macros

So I'm supposed to be creating a macro to print out emails like w****@email.com but I feel like I have basically no grasp on macros or what python I can or cannot write in an html file with flask. Here's what I currently have though I know it's a mess since I've rewritten it about a dozen different ways and this one might even be the worst one so far.

lunch.py
from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def index():
    class User:
        email = None
    user = User()
    user.email = 'kenneth@teamtreehouse.com'
    return render_template('user.html', user=user, output=[])
templates/macro.html
{% macro hide_email(user) %}
    {% output.append(user.email[0]) %}
    {% for letter in (user.email.split('@'))[0] %}
        {% if user.email.split('@').index(letter) == 0 %}
            {% continue %}
        {% else %}
            {% output.append('*') %}
        {% endif %}
    {% endfor %}
    {% output.append('@') %}
    {% output.append((user.email.split('@'))[0]) %}
    {% output = ''.join(output) %}
{{ output }}
{% endmacro %}

1 Answer

Chris Freeman
MOD
Chris Freeman
Treehouse Moderator 68,423 Points

Try thinking from the perspective of processing the email address, as you decide which character needs outputting, simply display it. To display the current letter use {{ letter }}. If you need to output a literal at-sign, simply output a @.

Because Jinja2 converts to HTML, any spaces between the template tags, including indentation, will be reduced to a single whitespace character. So output letter by letter would end up as "c * * * * * * @ t r e e h o u s e . c o m".

You can manage Whitespace by using the template tag markers {%- and -%} instead of {% and %}.

Looking at your template flow:

{% macro hide_email(user) %}
    {% output.append(user.email[0]) %}
    {# for each letter in the username... #}
    {% for letter in (user.email.split('@'))[0] %}
        {# continue if the letter index matches 0 (first) #}
        {% if user.email.split('@').index(letter) == 0 %}
            {% continue %}
        {% else %}
             {# otherwise output an asterisk #}
            {% output.append('*') %}
        {% endif %}
    {% endfor %}
    {# output the at-sign #}
    {% output.append('@') %}
    {# output the domain name #}
    {% output.append((user.email.split('@'))[0]) %}
    {% output = ''.join(output) %}
{{ output }}
{% endmacro %}

There are some issues with this flow.

  • simply display the output you wish as you progress instead of creating an output variable.
  • Instead of "continuing" on the first character, you likely meant to print it using {{ letter}}.
  • If the current letter happens to be a repeat of the first letter, it will be "continued" instead of printing.
  • Look at the Whitespace doc above to manage the spaces between the tags and end up with a compact output.

SPOILERS: If you find yourself still stuck. You can look at this solution or this solution

William Watlington
William Watlington
3,347 Points

Thanks. I realized the duplicate problem when I tried to just write it as a normal .py in pycharm. Thanks as always! I definitely need to learn a lot more about html after I finish this track.