Placeholder Image

字幕表 動画を再生する

  • - Hello, welcome to Coding Challenge: Logo Interpreter,

  • part 2, I'm a little bit scared of this.

  • (clears throat) All right, so what's going on?

  • Where are we, why am I here?

  • You might remember me from Logo Interpreter Coding Challenge

  • number 121, look that's me,

  • I'm almost wearing the same clothes.

  • This is a challenge where I looked at

  • the Logo programming language, a language from

  • designed in 1967, turtle graphics,

  • you might be familiar with,

  • I talked a bit more about it in that video.

  • I encourage you to read about the history

  • and also to check out the Logo Foundation

  • which is the foundation that supports a variety

  • of wonderful initiatives, including Scratch Day.

  • So check that out but what I did

  • was I made this Logo interpreter that is able

  • to interpret simple commands like forward 60,

  • left 90, forward 100.

  • So while this implementation of Logo

  • interpreting these Logo commands

  • like forward, left, forward, et cetera works,

  • it's missing crucial components.

  • And so there are many commands in Logo

  • and I implemented pen up, pen down, some of these,

  • but one of the most important ones

  • that I did not implement is repeat.

  • So this is a tutorial from a Brown University page

  • about the history of Logo that I'll also link to

  • in this video's description,

  • but what I want to attempt to do is

  • add the repeat functionality which you would think

  • would be a really simple thing,

  • but it's a little bit more complicated than,

  • well, there are some simple ways probably to do it,

  • and I will point out, in fact, that when I posted

  • this code, 16 pull requests came in with suggestions

  • and techniques for how to implement repeat,

  • and I would encourage you to go check all these out.

  • I want to highlight one of them that was pretty interesting

  • to me, I'm going to look for it, Regex implementation,

  • is this the one I'm looking for?

  • Yeah, this one, oh yeah, I love this,

  • which is just basically using a regular expression

  • to search for the repeat command

  • and then just replace the repeat command

  • in the string itself with what's the thing

  • to repeat multiple times.

  • So kind of like unrolling the string recursively

  • with a regular expression.

  • Pretty wild implementation.

  • I'm not going to use that one,

  • I'm going to try to spin up my own.

  • So this is my idea.

  • So, one thing that I think will help

  • is object oriented programming.

  • What if I have this idea of a command class?

  • So I make this idea of a command class

  • and it has the name of the command.

  • That could be forward,

  • left,

  • picks the pen up, et cetera.

  • It has an argument

  • so if the command is forward,

  • maybe I would have an argument like 100.

  • And by the way, the command could be repeat

  • and I know I'm about to leave your view here.

  • Repeat and then the argument could be a number also

  • 'cause you're going to repeat something

  • a certain number of times.

  • So you have this idea of a command class.

  • And then maybe what I think would be useful

  • is to create a parser object.

  • And actually, instead of using split,

  • so I used split as a way of looking at the Logo instructions

  • and just splitting it into a big array,

  • but I think what I want to try to do

  • in the most absurd thing ever is just actually step through

  • the string one character at a time so that I have

  • the idea of a parser is keeping track of a index.

  • So the parser is always has basically a pointer

  • into the command and can step through

  • and if it finds repeat, it can then pull out a chunk,

  • it can do all sorts of stuff.

  • So, if what I'm kind of thinking about here

  • is this idea of a command.

  • A command could just be a thing that you execute

  • with an argument but if the command is repeat,

  • then it could also have a list of,

  • it could have an array of its own commands,

  • that those are the things you repeat.

  • And then inside of this array, there could be a command

  • that is a repeat command so it could nested and recursive.

  • So this is my idea, I have not actually,

  • I thought about this quite a bit

  • and probably helped by looking at everybody's pull requests

  • so I don't know to what extent this is an original idea

  • or it just came from suggestions,

  • but it through osmosis, my brain has come up

  • with this idea but I have not tried to implement it

  • so what you are about to watch is me actually trying

  • to implement this for the first time,

  • and it might be a terrible idea and things will go wrong

  • and you'll probably notice this video is 342 hours long,

  • but if you want to stick with me, here we go.

  • Okay, so let me go to the code.

  • I'm going to keep the code that I had before,

  • I'm going to add a new JavaScript file called parser.

  • Maybe it should be interpreter,

  • I don't know why I'm going to call it parser.

  • Parser.js, I'm going to write a parser class

  • and the idea is that when you create the parser,

  • you give it some text.

  • So this is the full text that needs to parse

  • and then also it has an index which starts at 0, okay.

  • And, one of the functions that I would have here

  • is nextToken so it could maybe look and sort of find

  • the next token or something

  • in this text by stepping through it with the index, okay.

  • That's what I'm thinking about.

  • Now, I am also going to then create another JavaScript class

  • called command, and this would be,

  • this is what I'm talking about,

  • it would have a name and an argument.

  • And then it could also have potentially subcommands.

  • Recursively, a command could also include a list

  • of other commands.

  • So this is my idea, now, let's go to sketch.js

  • and basically,

  • this go turtle function, I'm actually going to just

  • basically take out what I did before

  • 'cause I don't think this, I'm not going to use split anymore

  • and I'm not going to have my own index here.

  • I'm going to say let parser = new parser with that code.

  • So let's just for example say console.log

  • and parser.nextToken.

  • So let me at least see if I can get parser.nextToken

  • to work, and so...

  • And this should probably return the token

  • so return "test".

  • So if I just run this now,

  • parser's not defined, right, I always forget this.

  • I've added a bunch of new JavaScript classes

  • so I want to make them separate, reference those files here.

  • Probably should get into bundling and building

  • and all that sort of stuff at some point.

  • Parser and command.

  • Let me go back to sketch, refresh, okay, so, great,

  • I see test there.

  • I have got my command but I didn't really get the token.

  • What I need to do is here, I really need to say all right,

  • so I'm going to step through the text one character at a time.

  • So what I mean by that is I'm going to say let char = this.text

  • charAt

  • this.index, okay.

  • So, while the character is not a,

  • I guess I could use a regular expression here.

  • So, I want to...

  • Let me just say, let me just do it this way for a second.

  • While the character is not a space.

  • What I want to do is I'm going to start with an empty token,

  • and I am going to say,

  • oh I don't need a...

  • While the character is not a space, token += the character,

  • character = this.text.charAt,

  • charAt ++this.index.

  • So what's going on here?

  • The idea here and, again, I could use regular expression

  • and substring but I'm trying to do this in a very manual way

  • to understand it.

  • What I'm doing is I'm saying let me look

  • at the first character and as long as that character

  • is not a space, I'm going to add that character

  • to my token and then look at the next character.

  • And this is basically, remember, this is something

  • I covered in the first part of the challenge.

  • This.index ++ this.index is increasing the index by 1

  • and giving back that new value.

  • So now if I say return token,

  • let's see what happens.

  • Refresh.

  • This text chatAt, charAt, a little typo there.

  • There we go, look.

  • (bell dings)

  • I got the first token, that's great.

  • Now, what if I now want to say

  • here

  • next token?

  • Ooh, it got a space, so look at this,

  • a space is not a valid token so what I can actually do here,

  • back into parser, is I can actually say if,

  • if char = a space,

  • return next,

  • increase the index, go to the next one

  • and return this.nextToken.

  • So this is a way of basically skipping and, again,

  • this is definitely a clear example

  • of I'll refactor this later,

  • I need a little theme music there for that,

  • but,

  • this is a start, okay,

  • so this is basically saying ignore

  • the space and so now,

  • we can say I've got forward 60,

  • but here's what I want to do really.

  • Here, I want to say...

  • And let me actually, let me use a regular expression here.

  • So I'm going to say,

  • there's a category of command which is like

  • a movement command, forward, backward, right, left,

  • so I'm going to say that would be a regular expression

  • that is forward or backward, this is fb followed by d

  • or left or right followed by a t

  • and probably, I should probably also make sure

  • it's the full string,

  • so put this beginning and end.

  • So now I could say

  • let token = parser.nextToken

  • if movement

  • test(token)

  • so if it's a movement command,

  • then create a new command

  • with token and token and parser.nextToken.

  • Right, 'cause I think I said the command is,

  • I said the name of the command and the argument

  • and the argument always comes next.

  • So, again, I'm not doing a lot of error checking

  • for people making mistakes in their Logo code

  • but we'll get to that later, I suppose.

  • Okay, I'm setting myself up for hopefully being able

  • to do a repeat.

  • Where am I here?

  • So let's just see and actually let's make

  • an array of commands, I mean I might want to put

  • all the commands into an array or I might want

  • to process them one at a time, there's various ways

  • of doing this but let's actually put it

  • into an array right now, I think that'll be helpful.

  • Oops, okay, so let's see and now let's look at commands.

  • Okay, refresh, look at that, I've got a command

  • with arguments, the name is forward, the argument is 60

  • and it doesn't have any subcommands

  • because it's not a repeat.

  • Woo, I like this so far.

  • So now, hmm, this is where I'm going to get into trouble.

  • Let's do something like while parser

  • is not empty, while parser has remainingTokens,

  • I don't know, come up with a better name for that.

  • While parser has remainingTokens, keep doing this.

  • So what does it mean here in the parser

  • to say remeainingTokens, well, on the one hand,

  • I can just return this.index is less than this.text.length

  • because if the index has moved past the end of the text,

  • then there's nothing left.

  • Hmm.

  • I'm wondering if this is going,

  • I bet you I'm going to get an infinite loop here

  • but let's just give it a try anyway.

  • Yes.

  • So I have an infinite loop, I could tell

  • because everything went blank, this is just there,

  • so I'm going to actually, unfortunately, have to

  • kill this page, whoops, ah.

  • Next token, there are situations where if it hits

  • the bracket, bracket is not a space, bracket is not a...

  • So, ah, I guess what I could do here

  • is if char, I mean this is really terrible

  • or

  • if it's one of these brackets,

  • then,

  • return, then also go up by an index

  • and return that character.

  • So this definitely accounts for another thing.

  • So, again, this could be condensed and I could maybe use

  • some more clever ways of doing this

  • but if it's a space, ignore.

  • If it's a bracket, whoops, if it's...

  • And actually, I'm going to want to do something for it's

  • a repeat, but anyway, if it's a bracket, send that back.

  • And,

  • otherwise, accumulate

  • until a space or bracket,

  • but, okay, there's so many problems with this

  • but I have to build it one step at a time.

  • If you're willing to stick with me

  • and keep watching this video, then more power to you, okay.

  • Let's see if I manage to not have an infinite loop.

  • Still infinite loop.

  • While character's not a space, keep going up

  • and this could get stuck.

  • Or, while character space and this.index

  • is less than this.text.length.

  • So I've also got to check to make sure I'm not hitting

  • the end, oh there we go, okay (laughing).

  • All right, so that was definitely the problem.

  • Now at least my infinite loop is gone.

  • Let's look at these commands.

  • So forward 60, right 120, so this is good.

  • This is what I wanted it to be.

  • But I need to be able to account for the repeat.

  • So this is good, this is giving me a list of commands

  • but what if

  • the token

  • that I get back, now I need to deal with repeat.

  • So, if it is a movement,

  • I should also have something

  • for a pen command which would really just be matching

  • a p at the beginning, right, any of the pen commands

  • match just a p so I should say else if

  • pen

  • test token,

  • so a pen command

  • is just a command with just the token, no argument.

  • And now I could, in theory,

  • if I added a pen up command, we would see

  • pen up is in there with no argument but that's fine,

  • so that's good, so this would work, oh why isn't it,

  • oh it's not drawing anything 'cause I'm not bothering

  • to draw, sorry, I keep opening up terminal by accident.

  • Okay, so I have now written a parser that can go

  • from token to token and can create commands and knows how

  • to handle any movement command or any pen command.

  • Oh and this.remaining tokens.

  • Ah, yes, great suggestion from the chat.

  • Abdillah Baghat suggests that here, I like this suggestion,

  • that this is already a test which is this.remaining,

  • remaining tokens, 'cause I have that function, right,

  • that already tests that here.

  • Great, okay, still working, all right.

  • Now it's time to deal with the repeat.

  • So I need to handle the repeat in a very unique way

  • and this is where I'm really going to get lost.

  • So repeat is just matching the repeat command.

  • So this could be a regular expression here.

  • So else if repeat

  • test token.

  • So now, what if I get a repeat command?

  • Then what I need to do is say,

  • so let command is a new command with the token.

  • Oh, and also the next token.

  • So I first get the number,

  • then what I need to do is I need to pull out, hmm,

  • I need to pull out everything within the brackets

  • so then what I want to say is the to repeat is the parser,

  • get repeat.

  • So I want to write a new function that then in the parser

  • looks for that starting bracket, looks for the end bracket

  • and just gives everything back (claps), okay.

  • So, in the parser now, I'm going to say getRepeat.

  • So I should first, basically find that first bracket.

  • So I want to, in theory, there could be spaces,

  • so char = this.text, this is really hard,

  • the way that I've gotten to this text.charAt this.index.

  • I should probably put that in a function

  • and then if while char,

  • I guess I could say, you know what, I could do this.

  • While this is

  • not equal to

  • this opening bracket,

  • while it's not equal to this opening bracket,

  • oh ++, right, I want to go ahead to the next one

  • but stick where I am, then just keep going,

  • and, and I guess need to make sure,

  • and

  • this.remainingTokens.

  • Now, I have found...

  • Basically I have found...

  • I'm going to say index, I'm just going to say

  • this.index.

  • This should console.log where the index is.

  • So I need to put a repeat in here.

  • So let's start with something really simple

  • like repeat three this.

  • And let's refresh, all right.

  • It got forward, it got right

  • and it got, ooh weird,

  • and it said 10.

  • Is that

  • 0 1 2 3 4 5 6

  • 7 8 9,

  • oh great,

  • so now it's at index 10, oh, perfect.

  • So now, ah, I love this.

  • Okay, so.

  • Commands push.

  • So this is actually a function,

  • I got to make a subparser of the sub thing.

  • Ooh.

  • Ah, yikes, I mean the recursion aspect of this, right,

  • because a repeat could have a repeat inside of it.

  • If a repeat couldn't have a repeat inside of it,

  • I'd kind of be done, maybe I should do that first.

  • This is going to be a really long video.

  • I know I keep saying that but it just is.

  • So now what I want is to

  • find the last one.

  • So...

  • Let's start = this.index.

  • Let end, now I need to do this again, move along

  • here,

  • and let end = this.index and then return this.text

  • substring start, end.

  • Let's see if this does what I think it should do.

  • And then,

  • let's see if it does what I think it should do.

  • Okay.

  • Command,

  • token,

  • whew, parser, nextToken,

  • let's just console.log this.

  • Console.log to repeat, okay.

  • Yes, oh okay, look at that, this is the thing to repeat

  • and the command is the repeat, perfect, ah, yes, okay,

  • but minus one, minus one, minus one.

  • So here, in parser, end minus one 'cause the index

  • is actually the index past that final bracket.

  • So now,

  • there we go.

  • The command is repeat, it's named repeat

  • and now I just need to fill the commands with an array

  • of the stuff that's inside of that to repeat.

  • So this, ah,

  • okay, I have an idea now.

  • This function...

  • Parse,

  • let commands.

  • I'm trying to think here, parse.

  • I need to write a recursive function now

  • where I come back and do this, then for those subcommands,

  • okay so let commands equal, this is going to be weird,

  • let me just try to do parse,

  • parser.parse,

  • is this what I want to let commands = parser.parse,

  • should all this be in the parser?

  • And then,

  • this would,

  • I don't know about putting this in the parser.

  • If this is in the parser,

  • parse, oh this is hard.

  • Okay.

  • While this

  • remaining tokens, next, so this I'm not so sure

  • about putting this in here but I'm going to.

  • So everywhere I said parser, I'm now saying this.

  • And then, I am saying let commands is be an array

  • and then basically, at the end here, I'm going to say

  • return commands, just give me a second,

  • I'm not going to do the recursion yet.

  • So let's see, let's see what happens here.

  • And then in Sketch, let commands = parser.parse,

  • console.log

  • commands.

  • This is crazy.

  • All right, sketch.

  • All right, that's good, that's good, hold on, hold on,

  • hold on, I'm thinking, I'm thinking,

  • oh there's a console.log here.

  • Where is there extra console.log?

  • Uh, it's 25 and 31.

  • Oh I have it twice, okay.

  • Okay, so now,

  • okay, okay, now, now, this is the hard part.

  • All right, so I have this to repeat

  • and then what I want to say is command.commands

  • equals (gasps)

  • parse,

  • this.parse to, this is what I want to do,

  • to repeat.

  • Okay.

  • So this isn't exactly going to work,

  • this is the idea of what I want to do.

  • But it's not right yet.

  • So close, it's not right because the parse command inside,

  • it's working with this particular,

  • the sort of global block of text.

  • Maybe it makes more sense for that not to be,

  • oh wait, no, no, no, I think I have an idea (gasps).

  • All I have to do is make a new parser here.

  • With the to repeat stuff and then

  • that equals

  • parser.parse, right?

  • Because then it would have, I think this might work.

  • Could this really work?

  • Let's think about this.

  • I'm basically saying hey, make a parser with all this code,

  • parse it and give me the commands.

  • The parser is going to do that and return that array

  • of commands but internally, oh, wait, wait, wait, wait,

  • yeah, it's going to make.

  • I think this, I mean, it's so hard to speak this.

  • Let's run it, let's run it.

  • This is going to produce a lot of errors or an infinite loop,

  • for sure. (drum roll)

  • (buzzer buzzing)

  • Cannot read property length of undefined parser.js line 7.

  • (vocalizing)

  • This.text, oh whoops, I took that out

  • when I was messing around with this idea.

  • Okay, not playing the drums but okay, command, repeat,

  • ah!

  • Ohhh.

  • (clapping)

  • I think that worked, okay, so I think this is a case

  • where I was figuring it out, trying to explain it,

  • all at the same time but I don't know

  • that I did that super successfully

  • so let me take a minute

  • to try to unpack what just happened.

  • Okay, and the idea here is that I have something like this,

  • repeat three,

  • forward 60, can you see that?

  • Yes, so the parser finds the first token

  • and makes a command

  • repeat

  • with three.

  • Then the parser, because it found a repeat,

  • asks for this as basically a substring

  • and it makes a new parser object with only this.

  • So the first parser object started with everything,

  • the new parser object just works on this

  • and makes a command.

  • So I really should put this in a json way.

  • So the idea here, and let's add some other stuff.

  • The way that it should work,

  • imagine if this had forward 60 here.

  • So the idea is that I would have an array

  • with commands and the first command would have name forward,

  • argument 60, then the next command would have name,

  • right,

  • repeat,

  • argument three but it knows it's a repeat,

  • it then goes and makes a parser for this

  • and the same way that this is a big array,

  • the parser now works on this to put it in an array here

  • with objects like forward 60, et cetera.

  • So in theory, this could even have another repeat inside

  • and that repeat would be in this array

  • with its own subcommands.

  • Hopefully that helps a little bit more.

  • But let's actually test this theory.

  • So let me go now to, let me, I'm afraid to type stuff

  • in here and break so I think what I'm going to do is just,

  • so let's start with

  • forward 60, repeat, let's just start with that first.

  • So we can see we got a forward

  • 60, no commands and a second command that says repeat three

  • with two other commands.

  • Okay.

  • Now what if I then put in here,

  • let me do it out here 'cause,

  • what if I do another repeat forward, oh so repeat four,

  • forward 10.

  • Let's look at this.

  • Okay, so.

  • There's still forward 60, then there's a repeat

  • and the repeat argument is three, there are three commands,

  • one of which is a repeat which has a subcommands in it.

  • (bell dings) (train whistle)

  • All right, I think this works, I mean I'm sure

  • this needs error handling but the basic idea

  • is actually working, wow this is very exciting to me.

  • All right, so what I need to do now

  • is to follow the instructions.

  • This should be, in theory, this should be the easy part.

  • So now that I have this commands, I can just say

  • for let command of commands

  • and now I forgot how I did this in the first place

  • 'cause I have this, oh boy, this is bad,

  • I have a,

  • I have this dictionary thing that I made

  • to execute these different functions, hmm,

  • so what do I want to do, this is called commands,

  • so I'm going to call this command dictionary.

  • Well I'll just call this commands, command list.

  • Command list, it's not a list.

  • Command lookup.

  • Command look up, boy that's a awkward variable name.

  • So what I want to do is now I want to say the name

  • is command.name and the argument is command.argument

  • and then I'm going to say,

  • I have to figure out if it's a repeat.

  • If name = repeat,

  • then for let i = 0, i is less than arg,

  • i++, right, 'cause I want to do whatever is,

  • and then I'm going to go through its commands.

  • I guess I could say, oh boy, oh, ah,

  • I need another recursive function to traverse it.

  • Aah.

  • Let me go back to something simpler.

  • Without anything nested.

  • Forward 60, repeat three times, okay so this idea

  • works.

  • But...

  • This needs to be a function, I need more recursion

  • or maybe I should be just doing this as I'm going.

  • So I'm going to call this execute

  • and executes a list of commands.

  • So if you execute a list of commands

  • and then you get the repeat, you need to execute,

  • command.commands.

  • Right, so in other words, I'm looking at the commands.

  • If it is a repeat, then I want to execute the sub commands

  • that are in these sub commands list

  • a certain number of times.

  • Otherwise, I can now say basically what I did

  • in the very first version of this challenge

  • which is to do what?

  • Command list name

  • arg.

  • So the idea is I'm looking up the command list,

  • in the command list, by the name with an argument.

  • So that will then go here and say if it's forward,

  • it will execute this function,

  • moving the turtle forward by an amount.

  • I think there's a lot of redundant extra code now

  • but this is fine.

  • Let's see

  • what happens.

  • Syntax error.

  • Oh this has to say function.

  • I'm not in an object anymore.

  • All right, mm, so, hmm,

  • what is that 100 100, so what's, oh,

  • oh I didn't execute anything.

  • Execute commands.

  • Command list is not defined.

  • Command lookup, okay, I can't remember what I call anything,

  • command lookup.

  • Hey!

  • (clapping) (bell dings)

  • This is working.

  • Wow, okay.

  • Dare I say this is complete?

  • Does anybody have access to the code

  • that produces this design?

  • I'm going to take a break and try to find it.

  • (train whistle) Okay, I'm back.

  • What you don't realize is about an hour passed

  • of me doing some horrific debugging

  • and if you want to find that, I will link

  • to the livestream version of this edited challenge

  • in the

  • video description, the thing that you're watching right now,

  • which is not, even though I am live,

  • it's not this, ah, okay, this, this is the code

  • using only repeats, left, pen up and pen downs

  • that will create this particular pattern

  • and if I go and grab this, I've pasted it here

  • and if I go back to my example and I paste it in...

  • (drum roll)

  • (buzzer buzzing) It doesn't work.

  • What's wrong?

  • Well, weirdly, I'm going to show you something weird.

  • If I put a space here and a space here, ah,

  • all of a sudden.

  • (horns playing) We have the pattern

  • we were looking for all long.

  • But there's some weird buggy stuff going on,

  • why is it a space but no space, here is the issue.

  • So it took a while to debug, I will show you a way

  • of finding, the way that I found the error was by looking

  • through, first of all the chat found this way before me

  • and kept suggesting it and I had to look and look and look.

  • Where I found it all of a sudden in this last repeat here,

  • this command right, right, it didn't pick up

  • the argument three, it's blank so that's certainly why

  • I'm not getting the pattern that I'm expecting to get.

  • Now why is it doing that?

  • Well the secret to that, it's not a secret so much,

  • lies in the fact of the way that I parsed this bracket,

  • right, remember if I have a repeat,

  • if I go here, right, I look for the first opening bracket,

  • that's the start, the first ending bracket

  • and that's the end but what if there's a nested repeat?

  • If there's a nested repeat, this is the starting bracket,

  • this is the ending bracket.

  • So it completely ignores, it pulls it off here

  • and then loses the way it's parsing, it loses that three

  • and somehow having a space in between there,

  • it kind of is able to still get that three by accident.

  • So what I really need to do is match the number of brackets.

  • All right, I have a different idea now.

  • What if, I think this finding the first one

  • and finding the last one in this weird double wild loop way

  • is kind of silly because all I need to do is keep track of,

  • I mean I do need to find the first one,

  • so let's stick with finding the first one

  • and then basically once I found that first one,

  • bracket, bracket count,

  • ah,

  • equals one.

  • So now, what I want to do is while bracket count

  • is greater than zero, I'm going to look at the character.

  • If character = and opening bracket,

  • then, ah, then increase the bracket count,

  • else if it = a closing bracket,

  • then decrease the bracket count.

  • And then I should have,

  • end should just now be wherever

  • the index is, wherever it last left off,

  • I might need to do minus 1, I'm not sure, right,

  • so this should be like, I'm basically finding

  • the first bracket, in this case,

  • there's noise and spaces there

  • and then I'm going to pull out,

  • I'm going to, I'm basically looking for where

  • that last bracket is and the last bracket is

  • and as the last bracket comes, bracket count will be zero,

  • I'll be done but if there are other brackets,

  • it's got to keep counting, okay.

  • (drum roll)

  • I should never use my drum sound because it always means

  • it's not going to work.

  • (clapping) (train whistle)

  • All right, there we go.

  • All right so this is complete, it works,

  • I'm very excited about that.

  • People have pointed out some examples

  • that I found, for example, I could try to make

  • this design, let's see what happens

  • if I post this in here.

  • Right, we could say, oh I'm kind of off

  • where my starting point is of but now,

  • I could start to really be creative and the line

  • is sort of thick here so I also feel like now that I'm doing

  • more complex stuff, I probably want

  • to change the stroke weight back to one.

  • And we can see that looks a little bit nicer.

  • I just want to show you something though amazing.

  • If we go back to the Logo repo which this is the state

  • before I've done this video and I go to pull requests

  • and I go, for example, to pull request number three

  • from TheTastefulToastie, you can see here are a whole bunch

  • of other ones that you can see that I could now try

  • that should work with my, and I'm going to show you something

  • that's going to blow your mind, this.

  • Ah, let's make this work, we have to make this work.

  • So I'm going to go, just before I leave,

  • think about other creative things you could add.

  • These are all the commands.

  • I am going to now go into index and HTML,

  • I'm going to put that in here, hold on, what's going on here?

  • Let me give a carriage return here,

  • let me paste in all of those commands.

  • Now I could now go back to here and do this.

  • We don't see anything.

  • So one thing that I really definitely need to do

  • is give it a much bigger canvas.

  • So let's go back to create canvas.

  • Have to finish with this.

  • 900 by 900,

  • something like that, refresh.

  • (gasps)

  • There it is.

  • Oh my goodness, this is nuts.

  • But it's a little off center, oh let's change it to 20 20

  • or zero, let's actually just change it to 0, 0.

  • And

  • make it a little bit wider.

  • Whoops.

  • There we go.

  • (train whistle)

  • it is The Coding Train logo made with literally with Logo

  • and all of these numbers here.

  • I hope you enjoyed this video,

  • there's so many things missing, right,

  • there are all these Logo, if you look at the history

  • of Logo and you look at the language of Logo,

  • there are lots of commands that I missed.

  • So I'll list some of those in the video's description,

  • try to implement those or also, color,

  • how would you incorporate color with this?

  • How would you think of other clever ways

  • to make this interactive in realtime

  • to allow people to play with it?

  • So, we now have a full interpreter here

  • and I'm finished with this project.

  • I can't wait to see what you make,

  • I'm going to add this code to the This Coding Train Logo

  • repository and I will accept pull requests

  • for implementing other commands, bug fixes,

  • adding things like color, making the interface

  • a little nicer so I'm probably going to close out most

  • of those pull requests that were implementations

  • of repeat, I thank you for them but this will be now

  • a community Logo interpreter project that will start

  • from the code that is in this video.

  • Goodbye, everyone, and see you in future coding challenges.

  • (upbeat music)

- Hello, welcome to Coding Challenge: Logo Interpreter,

字幕と単語

ワンタップで英和辞典検索 単語をクリックすると、意味が表示されます

B1 中級

コーディングチャレンジ#121.ロゴインタプリタパート2 (Coding Challenge #121.2: Logo Interpreter Part 2)

  • 3 0
    林宜悉 に公開 2021 年 01 月 14 日
動画の中の単語