Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

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,166 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.