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

Chen Wang
Chen Wang
7,371 Points

Macro 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.

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) %}
  {% part1, part2 = User.email.split('@')%}
  {%result=part1[0]%}
  {%for cha in part1%}
    {% if cha!=part1[0]%}
      result= result+'*'
    {endif}
  {%endfor%}
  {%result= result+ '@' + part2%}

  <div>{{result}}</div>
{% endmacro %}

I have viewed other users' answers to this question and it still doesn't work for me. Because the system just keeps saying "try again", I really have no idea what is wrong. Is this a little bit unreasonable?

Even our code has bugs, can the system just say something to help us debug?

Anyway, anyone has idea about this problem, I need your help...

3 Answers

Dan Johnson
Dan Johnson
40,533 Points

This challenge does have some issues with reporting errors. I tested methods out in Workspaces to get better feedback. Here's one of the ones I came up with that uses a loop:

{%- macro hide_email(user) -%}
  {#- Get the first letter of the email -#}
  {{user.email[0]}}
  {#- Get all the letters after the first, but before the @ -#}
  {%- for letter in user.email.split('@')[0][1:] -%}
    {{'*'}}
  {%- endfor -%}
  {#- Append the rest of the email on -#}
  {{ '@' + user.email.split('@')[1] }}
{%- endmacro -%}

You'll notice I avoided assignment. Assignment in Jinja is a bit different than in Python and wasn't covered in this course. If you want to go that route though, you can. I find it easier to follow than the loop method:

{% macro hide_email(user) %}
{%- set handle, domain = user.email.split("@") -%}
{%- set hidden = handle[0] + ("*" * handle[1:]|length) -%}
{{ hidden + "@" + domain }}
{%- endmacro %}

With Jinja, when you're dealing with output (stuff to be rendered in the HTML) use {{ }} over {% %}.

Chen Wang
Chen Wang
7,371 Points

Cool Dan! Thanks a lot!

Basically the key is to use '-' to avoid extra spacing in the for loop {%- for letter in user.email.split('@')[0][1:] -%} {{'*'}} {%- endfor -%}

that's if you same as I did failed due to extra spacing http://jinja.pocoo.org/docs/dev/templates/ "You can also strip whitespace in templates by hand. If you add a minus sign (-) to the start or end of a block (e.g. a For tag), a comment, or a variable expression, the whitespaces before or after that block will be removed:"

Well played

Khem Myrick
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Khem Myrick
Python Web Development Techdegree Graduate 18,701 Points

I don't know what background settings are implied in that challenge, but I was able to get Dan's solution to work without any of the '-' characters or modified spacing, since I'm not 100% on what those do or how they work, and I wasn't sure how to google the question. The test did seem very particular about only using single quotes and not double quotes? Anybody know if that's a jinja/flask/python/html thing?

David Lin
David Lin
35,864 Points

This also passes:

{% macro hide_email(user)%}
  {% set name, domain = user.email.split('@') %}
  {% set stars = (name|length - 1) * '*' %}
    {{ name[0] + stars + '@' + domain }}
{% endmacro %}
Pablo Xabron
Pablo Xabron
8,111 Points

Here's my solution

def hide_email(email):
    se =  email.split('@')
    return se[0][0] + ''.join(['*' for _ in se[0][1:]]) + "@" + se[1]
Jing Zhang
Jing Zhang
Courses Plus Student 6,465 Points

This is a question about jinja, not python.