Showing posts with label Ada Lovelace. Show all posts
Showing posts with label Ada Lovelace. Show all posts

Saturday, 24 April 2021

Ten sketches of actual programming projects

One of the greatest myths in development is that when developers write code, they simply park their asses down somewhere and type away till they're done. Nothing could be further from the truth. The process of writing code is thought. Lots of it. There has to be a rough outline before a developer even knows where to begin.

And one of the most common ways to provide a rough outline, is through sketching.

Yes, you read that right. Sketching. Pencil to paper. Crooked lines. Scribbled text. Stick figures. Here are some of the sketches I've done, that ultimately made the transition to working code. I thought it would be fun to provide a before-after dynamic. Notice how many of these sketches don't translate a hundred percent to the finished product. That's because requirements evolve. Sometimes, while I'm working on it mid-way, I hit upon a better way of implementing the idea. This may result in elements being moved around, text changed, and so on. That's just how it is.

1. Hong Kong Anti-extradition Protest Symbol (2019)

Whatever I eventually ended up thinking about the Anti-extradition Protests of 2019 in Hong Kong, there's no denying that this produced a lot of great art, some of which got me thinking about how one would represent one of these pieces in CSS.



The sketch was clumsy, the final product hopefully less so. It was basically the process of figuring out basic shapes in CSS and how to combine them. This was scribbled out over the course of devouring a lunch sandwich at my desk, and coded within the day in the evening.

2. Tic Tac Toe (2019)

Both the original and the Valentine's Day version were born from this little grid. It isn't much to look at, but there was more to this than just interface.



In here, I actually numbered the grid squares and thought about how to map out a win scenario, eventually going with an array as the main data structure.

3. Christmas-themed LESS Demo (2017)

I'm not sure at what point I decided to explore LESS, but it came in the form of making three different layouts to test my code with. Enter the 2017 Christmas-themed LESS Demo. Here, you can see the different layout drawings for each color.



Fun fact: The text in blue was preliminary thoughts for an unrelated piece of code for Ruby MadLibs.

4. Valentine Heart Animation (2019)

This was some idle doodling during an extremely boring meeting in which I was trying desperately not to fall asleep. Crude it may be, but it led to some amazing stuff.



I actually made this for my wife for Valentine's Day. She wasn't extremely impressed considering she's Chinese and doesn't celebrate Valentine's Day on 14th February... but it's the thought that counts, right?

5. The Pie Chart (2018)

While trying to produce a pie chart using CSS, there was a lot to think about in terms of angles and overlapping. The sketch I made during this thought process was extremely rudimentary. It certainly doesn't do justice to the insane amount of code I had to write in order to make this work.

The Pie Chart

However, work it did. For this, I had to think of all possible cases and how to handle them. Which was hard because at my level of CSS, I could only produce things at a right angle. Thus, the final result was a shit-ton of hacking.

6. Easter Bunny River Crossing Game (2019)

During another boring meeting, I sketched this beauty as my programmer brain clicked into full gear as to how I would make this work...


The final product differs a bit from the sketch. As you can see, I opted for full-body representations instead of cute icons. I can't recall the thought process behind it, other than "it would be cool".

7. Ada Lovelace Day Generator (2019)

During yet another boring meeting (see a pattern here?), this was born. I was thinking of ways to write a simple ReactJS app, and this came up. OK, so my drawing of Ada Lovelace looked more like some corporate suit but that was only meant to be a placeholder. I might have based the sketch on the office lady sitting opposite me at the meeting.


The controls for the number manipulation weren't as I originally envisioned. Certain considerations tend to come up only during implementation. But all is fine. I'm pretty happy with the outcome.

8. Scroll-down Christmas Carol (2016)

Work for the this was based on the scroll-down effect - but at that time I only knew how to use CSS to draw, and thus when rendering the caroler, I had to break it down into basic shapes. This was the sketch. Pretty rough, huh?


Well, as it turns out, I think my sketch actually had more life in it than the final product. Joke's on me!

9. CNY Rat SVG Animation (2020)

This one was an attempt by me to visualize how the string "2020" would morph into a graphical representation of a rat. As you can see, I had two versions, neither of which really resemble the final product.



On the other hand, these were lame. I think the end product is worlds better. I hit on the idea of using the bases of the "2"s as whiskers, while writing the code. But the sketches did give me that foundation to build on.

10. Contact Us Page (2019)

Another square drawing. This was pretty straightforward; I needed a layout for a typical Contact Us page, and just wanted to figure out what would go where.

Contact Us Page

You can even see the pin on what was my pathetic representation of a Google Map!

Whew, I'm done!

I'm definitely a worse artist than I am a developer, and that's saying something. Hopefully, from these, you can gain a greater appreciation of how this developer does things.

Sketch you later, alligator!
T___T

Sunday, 29 September 2019

Web Tutorial: Ada Lovelace Day Generator

We celebrate Ada Lovelace Day next month!

Ada Lovelace Day is a day dedicated by computer geeks and mathematicians worldwide, to a woman who is commonly recognized as the mother of modern computing, Ada Lovelace. It falls on the second Tuesday of October, and while it's nice and easy to remember, sometimes we just want the exact date for any given year.

That's where today's web tutorial comes in! Using ReactJS, we'll generate the exact date for Ada Lovelace Day from any user input year.

We begin with a HTML/ReactJS layout. Stuff will generally be in a div with an id of appContainer.
<!DOCTYPE html>
<html>
    <head>
        <title>Ada Lovelace Day</title>

        <style>

        </style>

        <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
        <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
        <script src="https://unpkg.com/babel-standalone@6.26.0/babel.js"></script>
    </head>

    <body>
        <div id="appContainer">

        </div>

        <script type="text/babel">

        </script>
    </body>
</html>


Now, in appContainer, we'll insert two more divs, with ids of adaContainer and genContainer, respectively.
        <div id="appContainer">
            <div id="adaContainer">

            </div>

            <div id="genContainer">

            </div>   
        </div>


genContainer will hold the components, but adaContainer will hold this lovely little image I found.

ada.png

So let's start styling. Set all divs to have a red outline. Then give appContainer this height and width, and align it to the middle of the screen.
        <style>
            div {outline: 1px solid #FF0000;}
           
            #appContainer
            {   
                height: 500px;           
                width: 450px;
                margin: 5% auto 0 auto;
            }   
        </style>


OK so far? Great.


Now, make sure both adaContainer and genContainer have 100% width. They'll have different heights. adaContainer will have a deep grey bottom border while genContainer will have a thicker light grey top border.
        <style>
            div {outline: 1px solid #FF0000;}
           
            #appContainer
            {   
                height: 500px;           
                width: 450px;
                margin: 5% auto 0 auto;
            }

            #adaContainer
            {   
                height: 300px;           
                width: 100%;
                border-bottom: 1px solid #444444;
            }

            #genContainer
            {   
                border-top: 2px solid #CCCCCC;
                height: 200px;           
                width: 100%;
            }       
        </style>


The special effect isn't all that apparent due to the red outline, but never mind for now.


Now use the image as adaContainer's background. Set the background-size property to contain. The image should be aligned bottom.
            #adaContainer
            {   
                height: 300px;           
                width: 100%;
                border-bottom: 1px solid #444444;
                background: url(ada.png) center bottom no-repeat;
                background-size: contain;
            }


Oh, we're off to a great start!


Now for some serious business!

In the script tag, declare the class AdaLovelaceDay with a constructor method, constructor(). In it, call the super() function using props as an argument (so that we can use this to set state), then set state with two properties - year (default 0) and adaLovelaceDay (default empty string). The class should also have a componentDidMount() method, because we want stuff to happen on page load. And of course, we'll have a render() method which returns the component markup.
        <script type="text/babel">
            class AdaLovelaceDay extends React.Component
            {
                constructor(props)
                {
                      super(props);
                      this.state =
                      {
                          "year": 0,
                          "adaLovelaceDay": ""
                      };
                  }

                componentDidMount()
                {

                }

                render()
                {
                    return (

                    );               
                }
            }

            ReactDOM.render(<AdaLovelaceDay />, document.getElementById("genContainer"));
        </script>


Bind the showAdaLovelaceDayForYear() method to the constructor, then declare the method.
                constructor(props)
                {
                      super(props);
                      this.state =
                      {
                          "year": 0,
                          "adaLovelaceDay": ""
                      };
                      this.showAdaLovelaceDayForYear = this.showAdaLovelaceDayForYear.bind(this);
                  }

                showAdaLovelaceDayForYear(renderYear)
                {

                }

                componentDidMount()
                {

                }


What the showAdaLovelaceDayForYear() method does is accept the parameter renderYear, which is a four-digit number representing the year for which we want to find the second Tuesday of October. So we start by declaring a variable, day, which we set to 1. And the variable tuesdays, which we set to 0.
                showAdaLovelaceDayForYear(renderYear)
                {
                    var day = 1;
                    var tuesdays = 0;
                }


Use a While loop, set to continue only if tuesdays is less than 2.
                showAdaLovelaceDayForYear(renderYear)
                {
                    var day = 1;
                    var tuesdays = 0;

                    while (tuesdays < 2)
                    {

                    }
                }


Declare a variable, october. Set it to a date using the Date() function, and passing in the arguments renderYear, 9 and day. Since day is 1, you've basically set october to the first day of October (we use 9 because the count starts at 0, so the 10th month, October, is represented by 9) in the year renderYear.
                showAdaLovelaceDayForYear(renderYear)
                {
                    var day = 1;
                    var tuesdays = 0;

                    while (tuesdays < 2)
                    {
                        var october = new Date(renderYear, 9, day);
                    }
                }


Use the getDay() method on october. If the result is 2, which means it's a Tuesday, increment tuesdays.
                showAdaLovelaceDayForYear(renderYear)
                {
                    var day = 1;
                    var tuesdays = 0;

                    while (tuesdays < 2)
                    {
                        var october = new Date(renderYear, 9, day);
                       
                        if (october.getDay() == 2) tuesdays++;
                    }
                }


If tuesdays is still less than 2 at this point, increment day. So this continues until you reach the second Tuesday of October, and by that time, day would be the... well, you get the idea.
                showAdaLovelaceDayForYear(renderYear)
                {
                    var day = 1;
                    var tuesdays = 0;

                    while (tuesdays < 2)
                    {
                        var october = new Date(renderYear, 9, day);
                       
                        if (october.getDay() == 2) tuesdays++;

                        if (tuesdays < 2) day++;
                    }
                }


The rest is fluff. Declare the variable adaLovelaceDay and set it to the value of day, then depending on what day of the month it is, append either "st", "nd" or "th" to it. It's not absolutely necessary, but it's pretty, so let's do it!
                showAdaLovelaceDayForYear(renderYear)
                {
                    var day = 1;
                    var tuesdays = 0;

                    while (tuesdays < 2)
                    {
                        var october = new Date(renderYear, 9, day);
                       
                        if (october.getDay() == 2) tuesdays++;

                        if (tuesdays < 2) day++;
                    }

                    var adaLovelaceDay = day;
                    if (day == 1 || day == 21 || day == 31)
                    {
                        adaLovelaceDay += "st";
                    }
                    else if (day == 2 || day == 12)
                    {
                        adaLovelaceDay += "nd";
                    }
                    else
                    {
                        adaLovelaceDay += "th";
                    }
                }


Finally set state. Use the setState() method to modify the properties year to renderYear and adaLovelaceDay to adaLovelaceDay.
                showAdaLovelaceDayForYear(renderYear)
                {
                    var day = 1;
                    var tuesdays = 0;

                    while (tuesdays < 2)
                    {
                        var october = new Date(renderYear, 9, day);
                       
                        if (october.getDay() == 2) tuesdays++;

                        if (tuesdays < 2) day++;
                    }

                    var adaLovelaceDay = day;
                    if (day == 1 || day == 21 || day == 31)
                    {
                        adaLovelaceDay += "st";
                    }
                    else if (day == 2 || day == 12)
                    {
                        adaLovelaceDay += "nd";
                    }
                    else
                    {
                        adaLovelaceDay += "th";
                    }

                    this.setState({"year": renderYear, "adaLovelaceDay" : adaLovelaceDay});
                }


In the componentDidMount() method, run the showAdaLovelaceDayForYear() method, passing in the current year as an argument. So upon page load, the first thing this script does is get Ada Lovelace Day for the current year.
                componentDidMount()
                {
                    this.showAdaLovelaceDayForYear((new Date()).getFullYear());
                }


That's all well and good, but...

Yeah, we're getting there. Since we've set the state and all, we'll need to display it. That's where render() comes in! It will return this div, id adaText, with the following template string.
                render()
                {
                    return (
                            <div className="adaText">
                                Ada Lovelace Day is on <b>{this.state.adaLovelaceDay} October</b>.
                            </div>
                    );               
                }


Style adaText. Just do what looks nice for you.
            #genContainer
            {   
                border-top: 2px solid #CCCCCC;
                height: 200px;           
                width: 100%;
            }   

            .adaText
            {
                height: 1.5em;
                width: 80%;
                margin: 0 auto 0 auto;
                padding-top: 1em;
                font-size: 16px;
                font-family: arial;
                text-align: center;
            }


And here we go! Ada Lovelace Day for 2019 is... 8th October!


Hold on, we're not done!

What's the point if we only get to forecast the current year? This would be a lot more useful if we included controls in the interface to input other years. We'll make the numbers of each four-digit year mutable via the interface.

In the render() method, declare an empty array, digitGens. Use a For loop to run 4 times.
                render()
                {
                    var digitGens = [];

                    for (var i = 0; i <= 3; i++)
                    {

                    }

                    return (
                            <div className="adaText">
                                Ada Lovelace Day is on <b>{this.state.adaLovelaceDay} October</b>.
                            </div>
                    );               
                }


On every iteration, push a new element into the digitGens array. It will be an object containing the properties number and id. number is set to each digit of the four digit year stored in the state. We'll first need to convert it to a string, then extract the character at the appropriate position. id is set to the current value of i in the For loop.
                render()
                {
                    var digitGens = [];

                    for (var i = 0; i <= 3; i++)
                    {
                        digitGens.push
                        (
                            {
                                "number": this.state.year.toString().charAt(i),
                                "id": i
                            }
                        );
                    }

                    return (
                            <div className="adaText">
                                Ada Lovelace Day is on <b>{this.state.adaLovelaceDay} October</b>.
                            </div>
                    );               
                }


While we're here, give each element in digitGens a inc() and dec() method. That method will call this component's changeYear() method, passing in the argument true for incrementing, and false for decrementing. (I know, we haven't created the changeYear() method yet. Soon!) Also, since this would be out of scope inside that For loop, we first declare the variable functionParent and set it to the value of this, and then use functionParent in place of this in the For loop.
                render()
                {
                    var digitGens = [];
                    var functionParent = this;

                    for (var i = 0; i <= 3; i++)
                    {
                        digitGens.push
                        (
                            {
                                "number": this.state.year.toString().charAt(i),
                                "id": i,
                                "inc": function() {functionParent.changeYear(true);},
                                "dec": function() {functionParent.changeYear(false);}
                            }
                        );
                    }

                    return (
                            <div className="adaText">
                                Ada Lovelace Day is on <b>{this.state.adaLovelaceDay} October</b>.
                            </div>
                    );               
                }


Now, declare the variable digitGen (note the singular) and set it to the value of a map() method run on the digitGens array.
                render()
                {
                    var digitGens = [];
                    var functionParent = this;

                    for (var i = 0; i <= 3; i++)
                    {
                        digitGens.push
                        (
                            {
                                "number": this.state.year.toString().charAt(i),
                                "id": i,
                                "inc": function() {functionParent.changeYear(true);},
                                "dec": function() {functionParent.changeYear(false);}
                            }
                        );
                    }

                    var digitGen = digitGens.map(
                        (item, key) =>
                        {
                            return (

                            );
                        }
                    );

                    return (
                            <div className="adaText">
                                Ada Lovelace Day is on <b>{this.state.adaLovelaceDay} October</b>.
                            </div>
                    );               
                }


We're going to use the digitGens array to generate a series of four number-scrollers mini-components. So, what happens is that a div with class of yearGen (note that we use className in order to avoid confusing the Babel compiler) contains two divs. The first div is styled using genDigit and contains the number.
                    var digitGen = digitGens.map(
                        (item, key) =>
                        {
                            return (
                                <div className="yearGen">                                   
                                    <div className="genDigit">
                                        {item.number}
                                    </div>   
                                    <div>
                   
                                    </div>
                                </div>
                            );
                        }
                    );


The second div is styled using buttons and has an id of digit plus the current element's id property. It contains two buttons. The buttons have data attributes, namely, i. Set that value to the id property of the current element. The onClick event handlers in each button will call the current item's inc() and dec() methods respectively. The button's text are HTML symbols ▲ and ▼.
                    var digitGen = digitGens.map(
                        (item, key) =>
                        {
                            return (
                                <div className="yearGen">                                   
                                    <div className="genDigit">
                                        {item.number}
                                    </div>   
                                    <div id="digit{item.id}" className="buttons">
                                        <button data-i={item.id} onClick={item.inc}>&#9650;</button>
                                        <button data-i={item.id} onClick={item.dec}>&#9660;</button>                 
                                    </div>
                                </div>
                            );
                        }
                    );


Next, we enclose the returned div in an outer div, and style the outer div using genContent. Put the entire digitGen component in it, just before the div.
                    return (
                            <div className="genContent">
                                {digitGen}

                                <div className="adaText">
                                    Ada Lovelace Day is on <b>{this.state.adaLovelaceDay} October</b>.
                                </div>
                            </div>
                    ); 


Don't forget to create the changeYear() method! Leave it blank, for now.
                showAdaLovelaceDayForYear(renderYear)
                {
                    var day = 1;
                    var tuesdays = 0;

                    while (tuesdays < 2)
                    {
                        var october = new Date(renderYear, 9, day);
                       
                        if (october.getDay() == 2) tuesdays++;

                        if (tuesdays < 2) day++;
                    }

                    var adaLovelaceDay = day;
                    if (day == 1 || day == 21 || day == 31)
                    {
                        adaLovelaceDay += "st";
                    }
                    else if (day == 2 || day == 12)
                    {
                        adaLovelaceDay += "nd";
                    }
                    else
                    {
                        adaLovelaceDay += "th";
                    }

                    this.setState({"year": renderYear, "adaLovelaceDay" : adaLovelaceDay});
                }

                changeYear(inc)
                {

                }

                componentDidMount()
                {
                    this.showAdaLovelaceDayForYear((new Date()).getFullYear());
                }


Yikes. This looks like a horrible, horrible mess. Let's clean this up.


First, ensure that genContent occupies the full height and width of its parent.
            #genContainer
            {   
                border-top: 2px solid #CCCCCC;
                height: 200px;           
                width: 100%;
            }   

            .genContent
            {   
                height: 100%;           
                width: 100%;
            }

            .adaText
            {
                height: 1.5em;
                width: 80%;
                margin: 0 auto 0 auto;
                padding-top: 1em;
                font-size: 16px;
                font-family: arial;
                text-align: center;
            }


Each div styled using yearGen should be 150 pixels tall. They should take up 25% of their parent's width, because there are four of these suckers, and four of 25% makes up... 100%! Float them all left. genDigit basically determines how each number looks. Use personal taste here. But do center the text using the text-align property.
            .adaText
            {
                height: 1.5em;
                width: 80%;
                margin: 0 auto 0 auto;
                padding-top: 1em;
                font-size: 16px;
                font-family: arial;
                text-align: center;
            }   

            .yearGen
            {
                height: 150px;
                width: 25%;
                float: left;
            }   

            .genDigit
            {
                width: 100%;
                height: 100px;
                font-size: 80px;
                font-family: verdana;
                font-weight: bold;
                text-align: center;
            }


Much better.


Now for the buttons. The container, buttons, takes up full width and text content is centered. The button tags are styled to be small squares with rounded corners, and a little margin.
            .genDigit
            {
                width: 100%;
                height: 100px;
                font-size: 80px;
                font-family: verdana;
                font-weight: bold;
                text-align: center;
            }   

            .buttons
            {
                width: 100%;
                text-align: center;
            }   

            button
            {
                margin: 0.25em;
                width: 2.5em;
                height: 2.5em;
                text-align: center;
                border-radius: 20%;
            }


Excellent!


To prevent the text from overlapping, set the clear property to both.
            .adaText
            {
                clear: both;
                height: 1.5em;
                width: 80%;
                margin: 0 auto 0 auto;
                padding-top: 1em;
                font-size: 16px;
                font-family: arial;
                text-align: center;
            }   


Yep...


And hey, while you're at it, remove the red lines.
div {outline: 0px solid #FF0000;}


Great!


Now let's deal with the changeYear() method. Declare yearString and set it to the state object's year property, converted to a string. Then declare digits, which will be an array of yearString's numbers.
                changeYear(inc)
                {
                    var yearString = this.state.year.toString();
                    var digits = yearString.split("");
                }


Finally, declare index, which will be the element's dataset's custom attribute i. Remember setting that while creating the sub-elements? This will tell you which number's buttons are being clicked.
                changeYear(inc)
                {
                    var yearString = this.state.year.toString();
                    var digits = yearString.split("");
                    var index = parseInt(event.target.dataset["i"]);
                }


Now, use the map() method and the parseInt() function to convert all elements of the digits array back to numbers.
                changeYear(inc)
                {
                    var yearString = this.state.year.toString();
                    var digits = yearString.split("");
                    var index = parseInt(event.target.dataset["i"]);

                    digits = digits.map(function(x) {return parseInt(x)});
                }


inc is true if incrementing, and false if decrementing. So if inc is true, check if the digit to be incremented is less than 9, and increment the number if so. This is to set a limit for the number... because in a year string you obviously can't go above 9.
                changeYear(inc)
                {
                    var yearString = this.state.year.toString();
                    var digits = yearString.split("");
                    var index = parseInt(event.target.dataset["i"]);

                    digits = digits.map(function(x) {return parseInt(x)});

                    if (inc)
                    {
                        if (digits[index] < 9) digits[index]++;
                    }
                    else
                    {
                    
                    }
                }


If it's decrementing, more checks are needed. We don't want the first digit to be a 0 ever, so first check if it's the first digit (i.e. index is 0), then decrement only if the number is greater than 1. That means you get a 1, minimum.
                changeYear(inc)
                {
                    var yearString = this.state.year.toString();
                    var digits = yearString.split("");
                    var index = parseInt(event.target.dataset["i"]);

                    digits = digits.map(function(x) {return parseInt(x)});

                    if (inc)
                    {
                        if (digits[index] < 9) digits[index]++;
                    }
                    else
                    {
                        if (index == 0)
                        {
                            if (digits[index] > 1)
                            {
                                digits[index]--;
                            }   
                        }
                        else
                        {
                       
                        }                      
                    }
                }


If it's any number other than the first, check if the number is more than 0 before decrementing. That means all other numbers can be decremented all the way to 0.
                changeYear(inc)
                {
                    var yearString = this.state.year.toString();
                    var digits = yearString.split("");
                    var index = parseInt(event.target.dataset["i"]);

                    digits = digits.map(function(x) {return parseInt(x)});

                    if (inc)
                    {
                        if (digits[index] < 9) digits[index]++;
                    }
                    else
                    {
                        if (index == 0)
                        {
                            if (digits[index] > 1)
                            {
                                digits[index]--;
                            }   
                        }
                        else
                        {
                            if (digits[index] > 0)
                            {
                                digits[index]--;
                            }                           
                        }                      
                    }
                }


Next, set yearString to be the joined string of all the numbers in the digits array. Then call the showAdaLovelaceDayForYear() method, passing in yearString converted back to an integer, as an argument. Remember that showAdaLovelaceDayForYear() changes the state of the component, updating the year and adaLovelaceDay properties?
                changeYear(inc)
                {
                    var yearString = this.state.year.toString();
                    var digits = yearString.split("");
                    var index = parseInt(event.target.dataset["i"]);

                    digits = digits.map(function(x) {return parseInt(x)});

                    if (inc)
                    {
                        if (digits[index] < 9) digits[index]++;
                    }
                    else
                    {
                        if (index == 0)
                        {
                            if (digits[index] > 1)
                            {
                                digits[index]--;
                            }   
                        }
                        else
                        {
                            if (digits[index] > 0)
                            {
                                digits[index]--;
                            }                           
                        }                      
                    }

                    yearString = digits.join("");

                    this.showAdaLovelaceDayForYear(parseInt(yearString));
                }


Well, now click on the buttons, increment and decrement as you wish, and the generated Ada Lovelace Day should change! That's the power of ReactJS binding, right there. Try changing the year to 2018. Does Ada Lovelace Day change to 9th October?


Wishing you all a happy and productive Ada Lovelace Day!

Decades after her death, look how far we've come. It's nice to remember the amazing woman who got us started down the road towards computing as we know it today.

All my Love(lace),
T___T