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

Zachary Hudson
PLUS
Zachary Hudson
Courses Plus Student 12,154 Points

macros challenge

Create a macro named hide_email. It should take a User as an argument. Print out the email attribute of the User in the following format: t***@example.com for the email test@example.com. This will require splitting the email string and using a for loop.

My code literally splits out what the question states under "bummer" and won't allow me to pass. I've tried changing User.email to make it validate, but maybe the validation is too harsh here?

See Screenshots:

http://take.ms/s5aS1 - Kenneth http://take.ms/DNyXA - Test

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)
templates/macro.html
{% macro hide_email(User) %}
  {{ User.email[0] }}
    {% for letter in User.email.split('@')[0][1:] %}
      {{ '*' }}
    {% endfor %}
    {{ '@' + User.email.split('@')[1] }}
{% endmacro %}

4 Answers

Chris Freeman
MOD
Chris Freeman
Treehouse Moderator 68,441 Points

Wow! This was a crazy "hard" challenge until reviewing the other Forum/Community discussions... and realized I had misspelled "endmacro" DOH!. But I learn a bunch from both Max Hirsh in this post, and Kenneth Love in this splitting-the-string post.

Kenneth's ("big hint") solution uses the with construct to simply the terms used in assembling the email from the parts:

{% with name, domain = user.email.split('@') %}
    {{ name[0] }}{% for letter in name[1:] %}*{% endfor %}
{% endwith %}

Combining with Max's solution to get:

{% macro hide_email(User) %}
  {% with name, domain = user.email.split('@') %}
    {{ name[0] }}{% for letter in name[1:] %}*{% endfor %}@{{ domain }}
  {% endwith %}
{% endmacro %}

Max's comment about the treatment of linebreaks and spaces in Jinja2, lead me to the Jinja2 document section on whitespace control. Interesting read. Adding a minus ('-') just inside the template tags will strip whitespace in that direction.

Comments can be added without affecting whitespace by using the format {#- comment here -#}

Taking this to the extreme, for example, the code below also passes the challenge:

{% macro hide_email(User) %}
  {% with name, domain = User.email.split('@') %}
    {{ name[0] }}  {#- display first character of name -#}
    {%- for letter in name[1:] -%}
      *
    {%- endfor -%}
    @
    {{- domain }}
  {% endwith %}
{% endmacro %}

Note: Using ```jinja as the format style above.

Kenneth Love
Kenneth Love
Treehouse Guest Teacher

Yeah, Jinja2 really likes to add whitespace.

Max Hirsh
Max Hirsh
16,773 Points

Good research! I hadn't thought to look through the documentation, but interesting to know there is a way to get rid of the extra whitespace feature.

Max Hirsh
Max Hirsh
16,773 Points

Hey Zach! Again, sorry for not solving this the first time around. It took me awhile to figure this out, but the way to solve this problem is seems to be to just put everything on one line! Jinja2 was maybe adding spaces after line breaks for some reason. Your answer was really close to working so I went ahead and edited everything to be on one line:

{% macro hide_email(User) %}
  {{ User.email[0] }}{% for letter in User.email.split('@')[0][1:] %}{{ '*' }}{% endfor %}{{ '@' + User.email.split('@')[1] }}
{% endmacro %}

A slight modification that I tried was just putting static strings as text, without enclosing them in brackets like so:

{% macro hide_email(User) %}
  {{ User.email[0] }}{% for letter in User.email.split('@')[0][1:] %}*{% endfor %}@{{ User.email.split('@')[1] }}
{% endmacro %}

So yeah. I'm not sure why jinja2 automatically adds spaces after linebreaks (maybe it's not liking the indentation?), but if you jumble everything into one line it should work. Hope this helps and sorry solving this took so long!

Zachary Hudson
PLUS
Zachary Hudson
Courses Plus Student 12,154 Points

Mh42. I tried. I can't figure out how to remove the whitespace between the characters. See comment above.