All right, everybody welcome to another exciting episode of logic live before we get started I just wanted to thank everybody for who sent just messages of support. We really appreciate it We all really appreciate it a lot goes into putting these together and I just really Amen a lot to get the support and also here like how much you're all enjoying these and so thank you very much for that This is the hey Dan. This is the first one of the logic lives We're doing with the webinar format So if you look in the control the control strip with the for to zoom the buttons, you'll see a Q&A button So if you do have any questions, please put them in the Q&A button or in the Q&A panel And what's great is they'll stay in there until they're answered It'll just make it easier to find them as opposed to scrolling up through the chat All right, we'll still keep an eye on the chat, but if you have a question throw it in Q&A So let's get started here. Welcome to writing Python scripts for flame with myself and Fred This episode of logic live is brought to you by synthesis Oceana synthesis Oceana provides solutions and two teams I'm sorry. Let's try that again. Take two synthesis Oceana provides solutions to keep teams connected and working They've been my Reseller for about 15 years. I couldn't do my job without them they keep us going on both coasts and They've always been supporters of the flame community. They sponsor user groups in New York, Toronto Detroit, Chicago, Atlanta, Dallas, and I'm sure more and they've always provided gifts or prizes rather for the one frame of white contest including two fabulous ice sculptures in Las Vegas and We will be back. I can't wait So to find out more about their remote workflow solutions go to synthesis.io synthesis Oceana supporting flame artists since 1997 Alright, we're gonna dive right in here. Let me stop this share and And say welcome to writing Python scripts for flame We're gonna go We're gonna this this presentation today is really designed for like the absolute beginner to the aspiring or maybe enthusiastic Intermediate, but I got interested in writing Python scripts for flame Bikes guess about a year and a little more than a year ago year and a year and a half ago You know at work where I was always like coming up against the constant pressures like the downward pressures of time and Budget of course and so I started to look at all the things I was doing repetitively and was curious to see if there was some way to Automate these to make the workflow more efficient to make my time More efficient and more more profitable Which maybe is more important now than ever so I sat down with with the flame documentation with Grant Kay's learning channel tutorials on Python with anything I could Google for a Python and and also with the help of a Wonderful human being when introduced in a moment I started down this this exciting journey. So let me just show you all a little bit of what's possible with the flame Python API and then we'll look at how you not only how you write your first script, but What some of the important things you need to know about Python are in order to really dive in so? Let me share the old screen one more time alright and very important thing And you want to start flame or flair or whatever app you're using You want to start it from the terminal because that'll give you the same kind of console feedback that you get in Linux Okay, when you do run a Python script It's possible to get feedback in this window either intentionally like if you would like to see something in there Or unintentionally like if something isn't working This is where you're gonna you're gonna where flames gonna tell you hey and you've you know You've you forgot to indent something properly again More on that I promise you as we dive in so you just navigate to your your Linux or your flame directory rather Which in my case is opt Autodesk flame 2021 and then bin all right and once you're in the bin directory. It's dot slash Start application this works on Linux as well, but you get the console for free so this will now do its thing it'll preserve a bunch of stuff and Here we go Wonderful all right, so let me open up a little desktop here and The Python commands or the Python scripts you have installed are all Visible or you activate them from the contextual menu from the right click. Okay, and Yes, I'm broadcasting in 239 Gabriel because I am the proud owner of one of these ultra wide monitors, which has been life-changing Apologies to everyone at home But wait, I'm broadcasting in 239, but it's not anamorphic. Okay, because we all hate anamorphic. Thank you All right, so let me show you some of the things that you can do For example, like whenever I would make a batch group add a batch group in flame I'd always have to call it whatever I call it, you know, this is scene one and Then I would always go through and I would name the schematic reels You know what I kind of always name schematic reels Source ref we all have our own formula and that's fine Pre comps and then I would add another one, you know For notes. I had a whole system been building this for years Okay, so I went ahead and modified one of the example Python scripts that you get with the flame documentation to Create a script. It's called create new batch group So when I click on that I get a new batch group with a default name All right, it can be whatever you want and then look here's a batch group with the four Schematic reels the way that I like them and I don't know if you caught this but every Python script That you install can have a hot key assigned to it So here I have very actually this is not only a hot key to launch or to create a new batch group This is the name of Elon Musk's new kid. I think if I if I remember what I read online So it's control Option command. I think control option command a so if I were to do that. Thank you Kego. I appreciate that Boom, there you go. You get another one. All right, so any one of these scripts you can do keyboard shortcuts Well Christopher I can tell you right now we have the the very person to bring that up to coming live So it's here on on on logic live But let's see what else what other kind of things we can do I Have here a spot or at least a dummy spot, right? It's a It's a slate and then I have the spot here and I know everyone here loves extreme reach. I I know that that's a long list of people who love extreme reach But extreme reach requires you to export with a certain number of frames Slate and a certain number of frames of black tail. I kept screwing that up So I wrote a little Python script for the timeline here That allows me to set extreme reach in and out points on My clip, okay, and then when I go to export that Here I have a script called extreme reach export and when I pick that It points to a directory by default and it won't work because I have this preset here from From an older version, but basically it will export The it will I have it automatically set to export this quick time and respect the in and out points or this clip and respect The in and out points, which is what extreme reach is going to want but let me show you something that I did actually test before we started today and that was Anybody here who's ever done any type of like episodic work your we have clients who any time we need to post something It needs to be posted with two different codecs one of the codecs You know in this case one of our episodic clients wanted DNX 36 and DNX 145 quick times and they wanted the DNX 36 quick times in a folder called DNX 36 And they wanted the DNX 145 quick times to be in a DNX I guess 115 really is what they wanted a folder and they wanted it to have an underscore HQ at the end of the name so I Wrote a little script here that will show you later that will automatically Export any selected clip using two export presets and if I go to the media hub here and just navigate to my desktop And of course give wiretap gateway permission to do all this exports I have a dated folder for today and then here's DNX 36 With the export and then a DNX 115 with the export underscore HQ Okay, little things like that Every time we start a project here at lively where I work I make an import folder or an import library rather that contains all the things I import like audio files or things from design or things from Our CG department so I have a script here that says create import library right and that boom creates an import library with anything that I would want and one of the first scripts that That I wrote that I was helped with by our lovely guest today was to create a shared library Script, which will give you a dialogue box The legend enter the artist name, right? And then you're gonna get a shared library with that artist name and in folders called to and from all right again Things that you do every day a million times a day Can then go ahead and be automated and the last thing I'll show you before we move on is in batch I Have here like the the very basic kind of setup that you get when you Do a create batch group from the timeline so I have here a clip and I have a work picture and Render node and just so you can see here. I can right click on the clip and I have Options like I can add an action node here if I want to right and then or to this clip here I could also add a mux node and automatically freeze it if I want right and then I'll happen at whatever frame. I'm at All right, that's labeled with the right number name I can select a bunch of things if I want and I can right click on there and encompass them, right? And give the compass a name all automatically and again, you can assign keyboard shortcuts to all of these things Or you can do what? What I always what I love to do it, you know every time We break out a spot and break out the shots. We have to prep for like a client session You know where we need to do red pen notes for cleanup make notes for other artists or the artists that are helping us out and So I made a little script here where I can right-click on any batch group Right and create what I call my like just basic batch setup. Actually Make sure that the names are right here first things first let's name the reels with one script and do That with another script and so what this does automatically there are all the things that I would do for every single shot by hand It adds a neat video ofx and it adds a right file node that has all the path and file format information baked in It's got a paint here for red pen notes that has My a setup that also loads a paint setup that contains I'm just cycling through here one two three four Some colors that I always use right for my Presets and a freeze or whatever frame I happen to be on a little Subtract here and an ad to subtract and add the the noise back on top and then some Resizes in between because there are times where we work You know if you have a client out there that shoots 8k and you're doing a snapchat deliverable There's really no reason to work in 8k So I have a little part of the script here that will down res and then up res back to the source And then you know an action and whatever else here to do in between But all this was created at the touch of a button if I had 50 shots I could right-click on all 50 batch groups and it would do this 50 times over and then instead of taking an hour or so To prepare for your client or to prepare to start working You're done in 10 seconds and there's an hour billable time you got back And we're gonna like I said we're gonna dive into these Python scripts all of your Python scripts live in a folder They live in a folder called opt Autodesk shared Python and if I go to that folder here Anything you put in this folder will appear in flame when you right-click and just to show you like In this episodic Exports folder or a script rather There's a bunch of things here that we're gonna go into detail on but you know Every Python script for flame starts with importing the flame module which has all the flame Python commands for the Python API And then you can see here I'm calling Export presets that you just make in the export menu, right? I just point to where they are on my either on my sand or in this case on my local drive Okay, and then down at the bottom of the script you have I Come to call this bracket. Hell. I'm sure there's a better name for this But inside all of these little open and closed brackets is where you put a label where you put the name for The script that shows up when you right-click and That is a very brief overview of what you can do with Python in flame and So I want to bring on now Someone who I've always respected but has become in the course of my my Python journey here a dear friend Coming to you live from from Montreal is the lovely and talented Fred Warren Fred. Are you there? Yes, I am. Hello, Wendy. Haha. Hello. How are you everyone? I'm doing good. Thank you so I I Set the stage here for you man we talked a little bit about Python and showed some examples of what you can do in flame, but it's really important for everybody to understand this is a Programming language you do need to understand Some foundational things in Python and order in order to do this so Fred is gonna take us through a little bit of of Well, I was gonna say Python for dummies, but no, no, no, no, it's Python for Andy's. Let's do it man No, I would say how what I would call it is like You set up in your intro, right? It's Python for people who are curious about it and one kind of a starting point To actually dig into it and know where to start to actually use the flame Python API with flame. So just like what you what you did Andy So I'm gonna share my desktop Here we're gonna go in flame and we're gonna bring the Python console So what I thought we would do is actually go over the first example that you did So you created a batch group with your custom action using Python API And what I wanted to show is how you could actually reach a point where you could discover That by yourself by testing things and the best the best tool that you can use to actually test the flame Python API is the Python console within within flame So you can open it from the flame menu at the bottom there So you go to the Python some menu and you open the Python console One thing to quickly mention is that flame still uses a flavor of Python 2.7 Okay, so it is not using Python 3 yet So there might be if you look at online documentation There might be some differences between a Python 2 and Python 3 so you need to make it Where you may you need to make sure that you are looking at example for Python 2 and also from one version to the other We are increasing the amount of things that are possible in the API So it's possible that if you look at a script that you were using With flame 2021 and then you try to use it in flame 2020.3 it might not use because the Later the latter may may not have the the component in the Python API that you are using So what we're gonna do is we're gonna look at the media panel here. We are trying to add a Badge group like you did and D and make it red it with this color coding So the first thing that you need to do as you mentioned is to import the flame The flame module inside your console so you can use those controls the first thing that you get That is a very good thing to use when you are actually Discovering what you you are trying to do is to use the print function Which will also always print in the console the objects that you're looking at or the Different attribute so we're gonna go over that so the first thing we're gonna do is try to print What is a the current workspace and right away you will see that you will get an error and This is where let me make that a little bit bigger here for you And this is what a really nice about the console is that you get instant feedback on the problems that you have that Do not work in your script. So in this example here I can say that I made a typo and if I rerun this again using either on Linux the control enter command or Shortcut or on Mac the command return So we you see that we're getting an object because Python is an object base language so all that you are going to do here is actually Modify objects using different commons different function and attributes So my object is flame the projects that current project on current current workspace So that's quite a long string. You don't want to type that every time So we're gonna store it in a variable So the variable can be any piece of text any string that you want So in my case ear for workspace. I just decided to use WS So I'm gonna store the that object in my WS variable. So now if I print WS I'll get the same object as I add with when I use the proper object string from the API So now That let's say, you know, which object you want to modify you can always rely on things that are That are available that are normal. Let's say to Python. So something like a duck string So we can a print the duck string. So the underscore underscore dot underscore underscore For the object that we store, which is the work workspace and it says object representing a workspace in frame One of the thing that is not available from Python But from the Python API that you can use to actually have a look at what's possible is the dot attributes Here so we if we print that property You're gonna get a list of all the attributes that are possible to a Either get or set for a given object in that case you see that list here that includes name so if I print The name of my workspace, so it's always the object dot the attributes or dot the function One trick to differentiate a attribute or properties from a function is that a function is something always something that has parentheses so if I print the the name of my Workspace I should have gotten No, sorry that that's logic. I forgot to change the name So we'll we'll rename it afterward, but I can Since it's object base, I can also define a variable for my attribute. So Using underscore name instead of name. So if I print my variable here, that's gonna give me again the same result Now we're gonna rename that to let's say a logic and because this one is always Is already named logic. So here what I did was to get The attributes now what we're gonna do is actually set it so we're gonna change it by saying the name equal a string and Selected equal true. We're gonna return that and you can say that it says logic and D and now it's the The entry that is selected The one thing that is really really really useful that also is like a Python Default function is L where you can say give me the L of any object. So if we run this here in My console, I'll get all the different methods Attributes of this also a what we call a read-only properties. So in that case here I can see that for example a workspace contains a desktop and the libraries So if I wanted to let's say store the workspace that desktop in a variable called desk I would run this and you can see just the just a thing that is a good practice is to always Print something to make sure that it was properly set And as Andy said if you run it through custom actions the print you can still put it The the output will be in the console instead of but the Mac terminal or the Linux console instead of in the Python console We're gonna move to the list so here now that you have seen that by Going to the L of the workspace that there was something called the stuff You can could then say okay, then show me the L for the desk Is there something about batch groups in there? So you see the different functions and you see that yes, you have something that is batch groups That is a list there and there's the function create batch group with all the documentation about it so If you say okay, I want to see the name of the batch groups and you run that you get an error because Badge group in that case here is not a a batch group object It's a list of batch group. So if we type so one of the thing that you can use is the type Ear function so if you run that you see that it returns that this is a list in the case of a list You have multiple different objects So if for example, you want to print the name of the first batch group You're gonna you're gonna need a square bracket and And give the index of the group in Python the index always starts at zero So even if you say that's the first batch that the second batch it always starts at zero So we're gonna say print for the first one and Now it's gonna say batch One thing that is really powerful even for like that beginner can use our for loops so a for loop is a loop in which you say for a Variable so in that case you just give the name of you want but since it's for all the batch groups and the batch groups list We're gonna say for a batch group in the list print the batch group name so you say for The variable in the list execute that command So if we do that you see that both items So it went it got the first batch group Print it then rerun the loop for the second batch group up until there are no more batch groups and do it If for example, we wanted to rename our batch group, then we could say Define a Int here, okay, that is one and say for the same loop Set the batch group name to logic So a string because in the case of the name we need to pass a string as an argument so logic plus the string of Then how you how you I would say that is you turn the end which is a number So not a float in that case a float would have like this small values in that case It's really in so you need to say This is a number but turn that into a string So you can say logic one logic two and then at the end of that loop you increase your variable by one So if we run that we're gonna have logic one and logic two Then we move on to Functions, so as you saw in the help we had the create batch group and you add like different things that you could set as Argument so in that case here you see that I have my function, which is for my desktop Create a batch group and the only thing that we're gonna do in that in that case is give it a name one of the most common error That you're gonna come across is that when you're trying to use a attribute for In a in a define like in a function like this You will need to set it to get value first To be able to use it So if sometimes if the console will return that this attribute is not color Colorball, then it means that you need you need to use the get value we just write it quickly like this and then in that case here We add the plus to create a space between the name of the workspace and I've added a three like this and Then you can always print the attributes for The object that you have just created because instead of just creating it We creating it. We created it by already storing it in a variable So then it's easier for you to refer to the object that you have just created and you are seeing Right away in the console here all the attributes for the new batch group including color So what we're gonna do is try to change the color of this batch group. So One thing to understand when we set when we set the name It was between the quotation marks It's not always this kind of value that must be passed as an argument, right? So in that case here, you see that if I try to set it in between any quotation marks Marks in gonna say that it doesn't work So what what you can do again is use the type Function to see and also the dot values So that values in that case here with the type will tell you that it's a tuple and if we only Print them without the type it's gonna give you the maximum and the minimum and maximum values So in the case of a tuple You're gonna use parentheses as well So the difference between a list and a tuple is that the list is between Square bracket and can be modified. You can happen items to a list You can remove items from a list where a tuple is also a list But yet that you can only modify the values you cannot modify the list itself So if we run that again, you see that this has read So that was it for my part in the console So we're gonna move quickly to something about the Python hooks so real quick though, does anybody have any questions there were a couple that popped up in the Q&A but They were about tokens and we'll get to that letter Well, we'll definitely get to that before the end but anything before Fred moves on from the console stuff That right onward. Okay. Okay, so there are different ways to execute Python comments in Flame we basically showed you to already so Andy showed you the using a custom action. So by adding a piece of script in a file that gonna Turn into a custom action in the contextual menu. So that's one of the ways. I showed you from the Python console Okay, you can execute the stuff. We just showed you there's also a way if you want to Always have something run when you start frame, for example You can use the start application command and pass it the dash s argument with the name of a script So when you gonna launch the application, it will execute that script on demand At this very specific time But there's also ways to actually execute Python commands every time an operation is Is run. So this is using a Python hook and I've just tried to illustrate very very basically What is a Python hook? So imagine that you go in flame. Okay, and you can perform some operations So you go to the batch tab. Okay, that's that's normal You add the right file node to your to your schematic and you attach it to a clip or a node That's that's correct. And then you render so to a to able to export the content of your right fine node on disk What happens when you render is that there's a Python hook attached to that function that is already there in your files So if you go to the application slash Python directory, they are Various some various Files that py files there that contain books for example batch export and the only difference From one user to the other is that if you do not like go and modify it It will just pass and nothing will happen when you will render But for some people you can go and actually put some code in there that will Do something when you render so if we go to my editor here and We look at the batch hook the py Okay, you're gonna see that When the batch export begin It's set to pass. So by default nothing will happen But I've modified the batch export end. So when we're done rendering the the frames What we're doing here is we are storing the path of the clip that we have exported and Right away after we are re-importing it in flame Using the dot import clip function and we're adding it to the schematic renders So if we go to batch and have a look at this Here So I have my little image here my right file I'm exporting to my a var temp export ear final version, of course Will we render it on this? I actually got my render, right? So if we go here and look you see that my final version EXR was rendered but what happened is that a clip was also added to my schematic in my Schematic renders here because of the look that I had set So if there's something that you always want to To be run a comment that every time you do something in the application Then you must have a look if there's a hook for it and use it One other hook that we thought would be useful for you to know about and I now so the Associated the function is a is actually an example that we're shipping with is the do watch folder function so if you look at what is happening here is Basically, we're look having a look if on this you have a var temp watch folder So this is something you can modify if you want to then we Look in the application if there's a destination library that is called watch folder and We then add we then inspect the watch folder on this Directory on this to see if there's something That was added there and we are using the flame schedule idle event Okay, and what is happening is that every time that Flame goes in idle mode. So it means that you stop for example moving the mouse The action is is run and the clip will be automatically imported and We are running that using a hook. So there's a hook that is app initialize So every time you start the application it is being initialized and in that case We only call the do watch folder function. So for a little demo. I will actually move Just like here. So you see that I have my do watch folder here. We're gonna go to my do watch folder and we're gonna make a copy of clip one and In my watch folder here when flame is idle, you will actually see that the the clip will Will will appear will will appear. Yeah drum roll. It's Yeah, okay, obviously That's working for this is what we call a live Yeah This is just like it's just that sometimes the something's the sometimes the idle time can be a little bit longer But it should definitely appear.  Was it an error? I Guess it didn't give you an error. So No, that that that should that should be that should be good what I can quickly show you is for example here so so this is This is the Python Self-holder I was talking about so you see that by default you have all the different Book files that are there and there's the watch folder. So you can have actually Files multiple files that are calling the same book They they need to be in one of the the location that that we are using by default for sure So if you go by default to Python examples So you you're gonna have a bunch of different examples there Including the watch folder, but those won't be called by the application They really need to be into the dot Python to actually be used in the application So just to summarize if we go here some of the resources as Andy said on the On the internet, of course on the web you have a lot of different resources examples One of the main one is just Python.org It gonna refer you to a lot of tutorials to a lot of documentation So that's a good entry point to actually have a look at There are also the examples that I just mentioned that you can actually have a look at it gives you some idea It's well documented If you think that it could be documented even more just let us know And finally if you go online on the flame user guide and in and the what's new There's always documentation about it. So if you go to the API documentation section There's something about the Python API the output of the L is there and is accessible online Obviously The advantage of running it from the console is that you as I said you get the live feedback on what what's not working But it's available online as well. All right, you know, I just going back to the the hook For expo for right file, you know, we have at lively. We are fortunate enough. We have a very robust infrastructure we have a big sand that we have taken advantage of and We're able to use a right file for like all of our pre comps all of the steps in between, you know that We were always using right file to export out like a pre-render why take up space on the stone, you know Why add extra stuff to the daily archives? Why have that media duplicated and triplicated across all of our machines when batch groups are copied? And so when when when this hook came out, we were able to have the same functionality with right file that we do with render notes So you go ahead and hit a right file and then you know Your image sequence is written to the sand or written to disk a link is automatically brought back in No space is taken on the stone and it's a beautiful thing and I know from my version What I ended up doing was adding to that hook one one more little command that would take the render and instead of pointing it Underneath the right file node. It would put it to the right of the right file node because you know Crazy, but just to show you that you know, you can customize these things to be anything that you want All right, I do have a question here from Diego Fred let me get maybe we can we can answer this one real quick He says is there a simple way to import image sequences using the API? Currently you have to manually enter the frame numbers in brackets like in the code below Wondering if there's already a tool somewhere that can detect image sequence patterns The of course, there's a there's a bunch of things that you can do with with Python to automate that If you are only using the import clips function, for example, it might be Very very well possible that by default it requires to get to pass the The the frames that you want to do but for sure You can you can modify it so that by default you auto detect all the different frames that are that are in a sequence and that you just use the the The all the sequence entirely by default. This is something that can be done for sure All right, cool Thank You Fred. Let's take a look at a script. I'm gonna share my screen again. All right, and Let's go in here to This Script that I have here for creating that import library, okay? So I have here My import flame right so this is what creates that library that has three folders in it, okay in design audio and CG so let's say we wanted to modify that to Make whatever you want it so you can see here, right? The first command we have is import flame which goes ahead and and gives you access to the flame API commands And then just like Fred was describing everybody can see this, right? Yes, okay good just like Fred described in in his presentation here I want to make a new library. Okay, so I declare a variable first called new library. All right I'm very creative person. So my new library is called new library and That equals flame that project that current underscore project that current under store workspace that create library Okay, it's a very long command, but you can save these all like in a text file, right? As a list of shortcuts and copy and paste them and and that way you only have to do it once and here I'm going to create a new library called import. All right, and Then I'm going to create some folders in there. So my next command is Called design folder and the command for that is design folder or the variable design folder equals new library Which is this? Dot create folder. So this is how you create a folder inside a library and it happens to be called design All right, and the same thing with audio and CG. All right, and then here we have a slightly different version of the the bracket hell at the bottom, but What this says here is I Have here In my contextual menu. I want to have a group called library a group called custom library and then I wanted to show a label called create import library and then run Main window, which is this the name of the script here. Okay, so if I toggle back to flame And again, this is saved in Opt Autodesk shared Python. I have my stuff organized into subfolders, but as long as it's in there. That's all you need Let's go ahead and Actually Take a look at this and flame one more time. Okay. I'll delete the old one All right, so if I click here and go to custom library, I see create import library and it Creates the import library for me, right? Well, let's go ahead and modify that and see what happens let's say You want to call this, you know import stuff Okay, and you wanted to add a fourth folder You can just copy and paste Whoops, I said copy and paste With a new line and we'll call this Work picture folder right And I'll go ahead and save just command s right go back into flame and right-click on my library and go to Custom library and you see it it only says create import library doesn't say create import I'm sorry create import library and down here. It's it's still showing the old Stuff it doesn't say import stuff. I don't have the fourth folder and that's because if you change a script If you add a script that folder or change a script that's in that folder you have to rescan your Python hooks In order for it to update The scripts which is accessible here in the flame menu or with the keyboard shortcut Control shift H and P. So when I rescan the Python hooks and Try to run this one more time Right it now says the right thing import stuff and it reflects the changes that I've made That's definitely something to remember any change that you make you have to you have to refresh the hooks or else You're not going to see the change This is where if I may and the This is where like it's really useful to start from the from the the console Because or in the shell because if you rescan the Python hooks and there's an error in your file This is where you're going to get the information one of the one of the very very common error With the Python is the indentation Python is really really picky about the indentation and the white space at the end of the line So it might prevent one of your script to work. So this is something to be on the lookout for for sure Definitely, and we just watched Last week the Silicon Valley episode where Richard broke up with his girlfriend because she preferred tabs to spaces and so I had a whole you know I was the only one in my family that was laughing basically Because I've been burned by this so many times But let's let's put that to the test here. You can see in my list of folders if I were to go ahead and You know add some more I this was my new this was my new line if I were to go ahead and not indent it and save And rescan the hooks Right I actually heard the error in my headphones here But if I go back to the terminal you can see here That that hook did not wear that script produced an error and it's telling me that it's in line seven, okay So if I were to go back sometimes it tells you that the it's not the indentation is not correct. Maybe I Want to go with that way it'll tell me that let's say yes, here we go indentation there are on line seven unexpected indentation I Tell you I have about 35 of these a day. So that's just showing you here that the indentation was not correct So yeah to Fred's point definitely have Launch the app to the console. Otherwise you'd get no feedback here letting you know what's going on And You'll just end up spouting profanities on the train like I Do whenever I'm doing my programming my Python scripting So let's look at one more and that is the shared library. Okay. I showed you that example here okay similar in In layout except there's an interesting little addition here, right? There's We're importing in addition to flame as a module and Fred, please for free to jump in and back me up on this We're importing some other modules one is OS which gives you more Commands to the OS, but also We're adding pi side to and Qt Widgets which allow you to do things like have pop-up windows and dialogue boxes to add information or a dialogue box that will show you a path like a Path on your file system somewhere So here we're Creating a variable called dlg which is short for dialogue which launches this Qt widgets Q Input dialogue which basically launches a dialogue box. Okay, and then says here Has with a has a label text which says enter the artist name. Okay, and then an if command Which I think means if this exists Run it with this value and so And then it creates one by default rather or but in the process it creates one more variable called name Which is a string of whatever it is you? Entered and now we get to flame. Okay, so this was kind of like the Qt widgets part of the Python script And here is the flame part of the Python script So I have a new variable called shared which creates a shared library as you can see here create shared library and The shared library rather than being named Like with something specific or something baked in like import or design or whatever It's using the value of name. It's using the value of whatever you typed into the dialogue box here. Okay, and then shared is the object and then here are the attributes so I Can go ahead after creating this I can automatically set set it to acquire Exclusive access so no one else can write into it I can then go and create folders inside of it and the folders I'm going to create are called from underscore plus name and to underscore plus name and note the quotes the quotes allow me to enter in a string of characters and then The plus name just adds whatever it is we typed in the dialogue box and then I now have another command here to release the exclusive access Okay, so it's basically like create the shared library which normally starts locked. All right, and then create two subfolders in there and then Lock it again. All right, and that's what we get with Create shared library. Let me show you that one more time And you get to Fred and from Fred. Whoops. I say you get to Fred and from Fred And these are great scripts because there's one You know, this is one of the first ones that that Fred helped me out with and from this I learned like oh, oh, okay. If I ever need a dialogue box for anything. This is all that I need to know. I just Excuse me. I copy these These little bits of information here and I can paste that into a new script and I'm often running I think do I have I think I might even have one more. I can show you that kind of showed the evolution of that Yes here create TVC delivery. All right every time we deliver a spotted lively we put it in its own real group Okay, so let me show you create TVC delivery, which once I learned how to create something and create and give it a name I ran with that a little bit of knowledge So I have here Here we go.  All right, and then here I have one called create TVC delivery and here's that same little command, right? Quick Qt widgets. There's the dialogue with some label text and then whatever you put in becomes the name So then I created a new variable called real group which equals What you need to know from the flame Python API to create a real group, which is flame project current Project current workspace desktop create real group using the name that was entered into the dialogue box, right? And then here I set the real group color. There's that tuple that Fred was talking about. These are the RGB values These are the different reels that I wanted in my in my real group. Each one has its name predefined and then You know, the one thing I couldn't figure out how to do was I didn't need the real called sequences That is that you get for free with a real group So this goes in and says for reels in the real group dot reels If you see a reel that's called sequences go ahead and delete it. Okay so Again here if I go ahead and say new real group You can see by default you get, you know your four reels and then you get sequences. I went ahead and did desktop Create TVC delivery and now I get a dialogue that asked me for either the name of the spot or the I add ID is key code type whoops the type that in And then you can see here I get a real group that has the name of the is key code I get the reels that I want name it went and deleted the sequences real and It makes the real group gold because gold But there I just wanted you all to see the Evolution of like, you know, you take one little you take one little Piece of code you learn for one script or or you learn in an example and you can easily apply it to other things Let's just look back here at the script one more time because I'm one and Fred I'm gonna need you to help me out with this here One of the things you can do with the Python API is define scopes All right and scopes mean like You can have a script that there are certain scripts that only really are applicable in batch You don't need to see those when you're trying to do something. That's only a library function Okay, so at the top of each script you can define a scope and you can see here like these are all things It can only be done in the desktop so I Have here define scope desktop selection and Then import flame and then for all things in the selection if they could possibly exist in what we call a pie desktop or a desktop object Then fine. This is a desktop And you Andy you have right clicked on the desktop So I will show these functions below or these scripts below that I get that did they get that right? Yeah, but didn't you a terrible? This is one of the difference for example using the Python console and the the custom action like Like you do because in the function Call from a custom action We are actually always returning the selection by default where the console you wouldn't get that So in that case you you are right and these saying that this This little function there is saying look if the selection is a pie desktop If it is return through through if it's not return false and then at the end of your script And when you return the structure that builds the contextual menu then we you can add your scope and this is where you would say only Display that function or that custom action on a desktop Mm-hmm. I got you and you again right. That's not Built into the Python console It has no way of knowing where where you are when you're when you're running the script, correct? That's correct. You can always like pass the selection They're selected entries for example of the media panel, but you can then scope it like you like you just in the same way That you just showed in the in the for the custom action Gotcha, cool. Hold on. Andy Davis has a question here So after you imported flame you then imported OS for pie side, could you instead use something else like? HOU to import Houdini Python calls within flame. I know this won't do anything complex But could it pass variables and data? Oh? Obviously what you need to be able like Flame needs to be able to Understand the command that you are passing, right? So the answer might be yes to your question and the we haven't tried that so maybe the what the What the what you get into the module from Houdini are just a bunch of Commands that are open and are accessible and are Are affecting let's say files on this or things like that that you that we could access But for example, you couldn't go in Houdini import flame and use comments like a create batch group or Stuff like that because it would refer to code that Houdini doesn't understand, right? So it might be the it might be true in the example that you you are you are asking about And then also just I guess one other thing that import OS wasn't really used in Like hearing in create and create real group. I guess this is a holdover from my my beginning days Hey, this is what I got from one example, and it didn't not work. So let me put it in everything But sometimes you try something you try something and then you do not use it because you use it from a Different way, but you forget to remove some part Exactly and like if it ain't broke, right? So yeah, I also I have a script in here that admittedly will probably not work on on my Mac here because I borrowed this from from my office, but Let's see that that creates Now it's not gonna work that's fine, but it creates a folder structure on on our sand for like creating Whenever we deliver a spot there are series of subfolders. So in that case OS would be useful there I thought it would be helpful to show off Or to show everybody rather a couple of things in the console here in batch Okay, just some some some basic things To get you started. So yeah, right? Let's say we wanted to create a node All right, like if we wanted to create a mux node, right? We start with import flame Okay, and then the command to create a node is flame dot batch dot create underscore node And then in parentheses We put what kind of node we want in this case. We want to create a mux node Whoops Quote there. So if I go ahead and it play Hey, there's a mux node. Okay Very exciting But I could also borrow from my little notes and shortcuts Text file here. I have Somewhere Well, I'll just type it out right I can always do this I could do Create equals flame dot batch dot create node And so now I could just type this for all the nodes. I want to create I could just type create and if I hit play I get the mux node a lot easier to type but Let's Do this let's call. Let's start with defining a variable called new mux. All right So new mux equals create mux and I'm going to get the same result except now I have a variable called new mux right Let's go ahead and have some more fun with that by adjusting the attributes so if I do new mux dot name equals I am a mux Okay Then you're gonna get a mux node with that label as a name, right? Which is great, we're gonna create a mux node, but then Another very very useful command here are the position commands All right, like if you want that mux by but by default a node is just created at zero zero like in the middle of your schematic Okay, but let's say I wanted to create a second mux node. All right called second mux Equals Create I'm big into mux notes Second mux dot name equals second mux and then we can define where we want it to go in In the schematic here, okay So we could do like second mux dot position X or POS underscore X equals New mux, which is our first one dot position underscore X plus 300 and so now if I go ahead and press play It'll show me that I screwed that up. What did I screw up here? Yeah Second mux Really Fred, I'm not seeing it I'm trying to Oh You can't start the name of the number. Let's try that. All right, so I'm just gonna copy this and paste it here and here Let's see if that Yay, there we go. Thank you so much Tim Farrell for the win. All right Which is great and One last thing is if you wanted to connect these right we type our connect command and You'd start off with your from which is new mux and The output of it that which is default right Fred Yes, okay, and then But for that you haven't specified connects or you'll go to you'll write you that the old The old command just denied me the opportunity to swear. What are you talking about? Input let me go back and do that zero Okay, so I'm gonna send it to find another here. So connect equals Flame dot batch dot connect nodes, right? All right, so I'll clear these and it didn't work. Oh, that's because new mux needs to be all caps here There we go. It's my hit play Now you have created two nodes you've created a connection. All right, so just simple examples of how you could you could play around here in the in the console to create nodes to label them to move them and And to connect them and so when I made that whole big giant set up here I first did a layout of the setup that I like or that I wanted like the result I wanted and then I went ahead and built it with those commands and yes It would be like radically and efficient to do that every time you were gonna make a make a batch graph But if you need to make the same thing 20 times four times a day Taking the time to do it once is extremely Time-saving. I think you just show like You just show what's the the console is useful for right? You're trying to build something maybe something that you you want to repeat often So you're using the console to try it and once you have actually what you were looking for then you can convert that into a custom action Put it in a file and then it you got your your custom action in your your right That's actually the bug and get the errors and things like that using the console is pretty good Mm-hmm. Yep, you mess around in here till you got what you wanted You can copy and paste it into a file. Yeah, and now you have it as a Python file Let's let's just bounce over and see what Questions we have here. There are a couple more in the Q&A and Chris Chris says I found a number of my Python scripts Don't show up in the hotkey editor. Is there a reason why that happens? That I would be curious to to know if the the scripts actually actually show In the contextual menus Because it might be that there was an error and if there's an error the the script won't be Loaded in flame. So there might be an error being returned and you might not see it in the in the shell So maybe this is something Chris that we can take offline and we can have a look at otherwise, I've I've never heard of a Of a script not showing in the the short cut editor. So there might be a problem, but I've never heard of that All right Barry says can you can you I'm sorry one more from Andy Davis? Is it possible to use the flame Python module to update versioned assets like a new fbx camera found on the server for example? Yes, yeah, you can out of the box I don't think that we have something that monitor if if something Ash changed, but this is certainly something like the pieces and the tools are there for you to do it That's for sure You would have for example a little bit like we did with the the watch folder example to actually watch if something Has been changed on disk and then it could trigger in action and update it Cool Barry asks do you can you program a color transform with a certain LUT or a CE I guess is aces IDT for example? No, right right now right now. There's no way to manipulate the color space of a clip in the flame Python API Barry I could show you I don't think I have it here at home, but I did I did write a script I was working on an episodic that had CDL for each shot or a lot for each shot. Oh, oh, yeah, okay. That's yeah, that's that's right Okay, that's the I think that's the way the work around I gave you Yeah, that was the workaround What I was it you can you can add a color management node and you can load a color management setup for that node Okay, and so if you happen to know in advance like what what LUT you need or you know what What LUT you need you could make a color management setup file that has that that Setting already or that custom or whatever it is already saved and then you could run a Python script that will Add the color management node and preload it with that saved setup. So that is a workaround and I can show you that offline. If you want, just just send me a message Jorge, would it be possible using Python to send elements from an archive to flame archive so they are restored in the background Is it so is it I guess Jorge you're wondering is there a way that you could if you to extract something from an archive using Python and have it loaded in the background maybe into another product like a non-active project or another workspace in that project Honestly about that Within the within flame and within the flame IPI the answer would be no But I'm not sure Outside of it if you couldn't do something about it And maybe this is something that we could look at the or gay and get back to you About maybe there's something that can be done, but that would be outside of the flame a Python API Gotcha And then Tim Farrell is asking Any plans to simplify the process I'm thinking of something like Photoshop actions which records your keystrokes and plays them back on command So something where like you could build a batch setup that you like for example, and then create a script out of that Is there anything like that? This is actually this is actually a very fragile emotionally You're gonna tell me that there is I'm probably Sorry and the there's something that we actually tried a Long time ago. I think that I showed a prototype of that like at any be 2006 or 2007 something like that, but unfortunately We it major roadblock Very very fast doing things like that So maybe that this is something that we could revisit In the future and see if like with newer technologies But there was like the problem was really more on the flame side than anything else. So So I'm not saying it's impossible, but it's right now It's a doubtful that you would see something like that in the short term Gotcha Let me show you guys two more things real quick Just now that we've talked about the scripts a little bit the first one is in the The episodic exports script. I just want to show you Maybe Maybe just maybe one thing that I could quickly mention It is something that we we've put in place last year, but we didn't really have the time to actually put it more into into effect and We anyway, we wanted to give the time to two people to actually Start looking into the Python API But we want to put in place a structure with where it would be much more easier to share Scripts and they are some people out there like Michael Stefan and the OR sharing scripts already, but So back to Tim's point We want to make it easier for people to Benefit from all of this without having To go through the asshole themselves to build the build of some some of the the scripts like this Take care Gonzalo And thank you in the episodic export script here now that we looked at a couple of things here I just wanted to point out All that this does this this this script here utilizes the flame export hook Okay Which is that called a exporter here high exporter? And so I have to and I shared this back with our first logic live I'm happy to share it again for this one here, but all that this does is You right click on a you right click on the clip whatever clip is selected. It's going to export it using Whatever the defined export presets are and these are just like export presets like we've all made a million of these I'm sure but when you go to export You can create a preset so you create your preset here save it and With whatever you want and then put the path to that preset here Okay, and so when I go ahead and click export like I showed at the beginning of this it's exporting it's Exporting that clip twice With each one of these presets so it goes out twice But I also have a version here in my script called manual. All right, which will using that that OS Module will go ahead and allow you to manually select the path All right, and this is just another example that dialogue box here So if you go to exports and manual a window opens up I have like a predefined area for it here I mean you can put it like you know if you always export to one folder you can put that in there but this allows you to pick the folder that you want and Export to that folder there Except of course Andy didn't test this before he went ahead and of course he picked the 32nd spot So we're just gonna stop that but anyway, I wanted you to see that there and then The the setup that I have that creates or the script rather that I have that creates this kind of default setup There's a bunch of stuff in here, but when you break it down, there's really not you know I mean all that it does is make sure that I'm working in a batch group It goes and looks for all the proper real names Right, so if it finds a real called schematic real one like if I didn't name them ahead of time it will change the names, okay? and Then you can see here for everything. I'm like defining a clip and giving it a position, right? Defining I'm creating a mux node here giving it a name and giving it a position Based on the original source clip node and so on and so on and so on and so on When I create the paint node for doing my red pens There's a command called load node setup which allows you to load a setup This is how I load a paint setup that has my colors predefined or if you have like a color management or anything If there's a setup that you always load if there's something like down here in the user bin that you always use That's another way to grab To grab that and then at the bottom here I define all the connections connect this to that and this to that and so on and so on and then I have You know bracket hell down here that where you can define the name of the script so That was a hopefully an informative little overview of the kind of things you can do with the Python API Oh, Andy David says one more can Python create setups that include linked expressions That's a good question. I've never tried it a the link expression should be part of the setup itself so the answer I Guess would be yes because there's a safe setup save a node setup function In batch old there's a you can save a batch setup or a individual node setup So if the linked expressions are saved into those setups then when you reload them, they should be reloaded But if you if you were trying to create it live like if you had If you were doing what I'm doing here and you wanted to create a setup you there is no specific Python create command to create a linked No, no, that's correct. You can do a node link. You can you know one of one of these. Whoops. I mean one of these I Mean one of these but there's no there's no like expression wise a copy link That's correct. That's not in the Python API. Cool Well, let's uh, I want to say thank you Fred. Thank you very much. This is a lot of fun I hope I thank you and this was great for everybody if anyone has any questions about it about Python in general Please feel free to reach out Let me just bring back the old What do you call it keynote thingy, which I have here somewhere and we'll wrap this up We have some upcoming logic live sessions, I want to tell you guys about first of all tonight At 6 p.m. We're doing a neat video deep dive with Tim from neat video and there's going to be a An exclusive discount code for everybody who tunes in Neat videos. Everybody knows is the greatest, you know noise reduction tool in the world But I certainly put my hand up. I'm only using the barest Minimum of its functionality and I know when Tim took me through everything that it can do There's so much more available. And so please tune in it's going to be great Next Sunday, we're going to do an interview with will Harris flame family product manager Followed by Maya for flame artists with Yuri temposki from Sao Paulo on May 24th Connected conforms for social deliverables with Brian Bailey. I just had to do this or we just had to do this last week And it's a nightmare and so anything we can do to simplify that is going to be much appreciated in June 7th We're going to do silhouette paint with our friends at Boris effects and June 14th resolve for flame artists with David John's who's a great great great guy out in LA You can find all kinds of great content on logic TV our website including My matchbox and Python resources. All right There is oh, you know, I'm going to actually stop this share and I just want to give a shout out to To Michael who I see is on here Um, what did I say that here we go a couple of things here? Um, as far as as far as Python scripts, definitely check out Pyflame.com. All right, this is Michael's Site where he's got some amazing Python scripts that are very easy to install even as an installer But I can't tell you how many times This one has saved my ass the paint node edit. All right How many times have you like had it set to single frame? But you wanted a sequence boom, I just recently found invert axis and Even today when I was preparing for the setup here Where did it go? Where did it go? Come on replace render nodes, right? There's a bug that every now and then you go to render your batch node and go to render your batch and it says I can't sorry. There's no render nodes, but there is a render node Well, you run this script and it replaces the render nodes with exact replicas of what was there And you're good to go. So a whole bunch of great stuff. You can also check out staphons at flame py.com the Make sure you go to the flame documentation and to api here Right and python api and you can check out here. These are all of the python api commands There are also examples here How to execute scripts how to run your for writing your first python scripts This is how I got started and a bunch of other great examples here Which uh, you know, even if if I you have something that isn't If you have an idea for a script and it's not expressly listed here as an example I guarantee you're going to need to do one one part of it. You can find in one part leads to another part leads to another part So definitely check that out Go back to the keynote Definitely, uh Check out all the logic live episodes on logic.tv. This one will be up as soon as I can get up there Please subscribe to our youtube channel. That's uh been doing great We appreciate it and of course a huge thank you again to cynesis oceana our sponsor Uh cynesis provides solutions to keep teams connected and working find out more about their remote workflow solutions at cynesis.io supporting flame artists since 1997 So that's it my friends. Thank you so much for joining us today Thank you for all your support and for all the good wishes and everything And uh, we'll see you all at 6 p.m. Tonight for the neat video deep dive. Take care everybody


Hello, I'm BDS Stevens, a senior handler with the Internet Storm Center and in this video we are going to look at some malware submitted by a reader. So I wrote a diary entry to explain how I did some of the D-DOS fiscation that I had to do for a sample submitted by a reader and it's a malicious document and that malicious document contains a PowerShell command that is DOS fiscated so let's take a look. Getting the command, the obfuscated command out of the malicious document is actually quite simple because it's hidden somewhere in the properties and just by doing a strings on that document and grabbing for PowerShell you get a command and so this is one of the ways that a PowerShell command or actually any command on the command line in Windows can be obfuscated via DOS which is called DOS fiscation so that's one of the methods and you can see here the cmd.exe with the slash c so we know this is a command here you see the PowerShell and this is what will be executed so that's actually concatenation of variables that is happening here and what is actually happening is that each number here is converted to a character but not using the ASCII table but using the table that is defined here in this variable you see set EA0 that's also what is referenced here EA0 and to get one character and that is concatenated in this command which is then executed here with the PowerShell so what we have to do to the obfuscate this is convert those numbers to characters according to this table and I have a generic tool to do that it's called numbers to string so let's do the command again here and pipe this into numbers to string and then you get this kind of output where all the numbers that are found here are converted to characters based on the ASCII table and like I said here it's not with ASCII table it's with this table and that is something too that you can do with numbers to string that is provide your own table for the conversion and that's what I'm going to do here next with option T for table I provide sorry I provide this table here this here until the ampersand ampersand so copy paste this like this okay and you get no output okay if you get no output with numbers to string that means that either no numbers were found or that an error occurred here we have a lot of numbers so a error must have occurred so we can use option E to see the error okay and the inner error is string index out of range so one of the numbers found here is too large for this table but we can quickly work around this by using option I I will ignore all errors like this you see and here now we have decoded this obfuscated power shell command and here you can see that it creates a net web client with URLs so it's a downloader it will download from those URLs right into disk and execute now if you take a close look you can see here that we we have some text here that doesn't actually look like part of the power shell command and that's because of the following and let me show you again here the command so here we have our numbers that starts with 49 but if you take a close look here we also have a number here 32 and here 0 1 9 2 and so on so those numbers are also taken into account by numbers to string it will just take all the numbers that it finds per line what we can do is tell numbers to string only to take numbers into account starting from a certain number we're going to do 49 here so I can say like this begin 49 like this okay and then you can see here that it starts with the assignment of a variable so that looks indeed to be the start of the power shell command the same with the end we also have numbers here and that is because after the 86 here we have a 0 0 0 1 an 86 and so on so those numbers are also taken into account and we can do the same and we can say okay 86 that's the last one that we want now but you have to know one thing that is that 86 itself it's actually no longer part of the command the encoded command 86 is the indicator of the end for the conversion because you can see here if percent s equals 86 then we do the power shell command so this is actually no longer part of it so we want to stop at 50 that's what I'm going to do here and 50 like this and then you get the complete power shell command now one more thing you no longer need in your error here we can do that away and then you also get the output there is actually no error anymore and that's because the index error was generated by that 86 number and that one was too large for the index in the table and that generated the error but now that we are no longer taking that number into consideration we get no error anymore and one last thing I want to show but let me first clear the output here so here we have the command and this is the command to do the decoding where with option t I copied the whole table you can also use another option to provide a table so let me erase this and that is with uppercase t and then you just need to provide the start starting string of the table and then numbers to string will extract any string that starts with that sequence and conceal that as a table so I can type here mkb here you can see that's the start of the table mkb and that's just enough to be able to identify the table and use that and then you also get your decoding


President Daniels, thank you so much for joining us. It's your first time on the This is Pretty podcast, and we appreciate your time. It's been a crazy year. So let's start with commencement, though. That was held outside at Ross State Stadium for the first time ever. And it went very well. Beautiful weather. You wrote in on the infamous couch cart. So tell me about that experience. Well, the couch that Ethan and Nathan put together was such a boiler maker thing to do, first of all.  And as long as the school's been here, we've had great tinkerers and inventors. And so, as I think you know, it's a go-cart engine with a garden cart. They bought it at the Menards or somewhere. And a couch that was exactly what a, I'll say, male student's college couch probably should look like. I remember those kind, holes in them, and springs almost coming out of them. Actually, quite a comfortable ride. You know, I told people it doesn't corner very well, but it has a good straight line acceleration. Yeah, it was quite the entrance. What was it like writing your commencement speech this year? I always do it or try to have a first draft done over Christmas vacation. It's my big homework assignment of the year. You know, I personally, although it is always a worry item for me, I think it's a good tradition at Purdue that whoever has this job, give that speech. For one thing, it simplifies the problem of who you invite, will somebody not like the choice. It probably ensures that we keep the, at least while I'm doing it, that we keep the ceremony a little bit concise and tight. But I worry over it because every student sitting there has worked awfully hard. And I feel like I should also try to say something that is meaningful.  And I try to do something that fits the times in the moment. Now, this year, as I wrote it, and it really didn't change much after New Year's, I was very conscious that this whole thing could be rendered obsolete because COVID is still evolving. And it certainly was back then. And so I thought, this might be something I have to start over on, but I didn't. And it seemed to be very well received. I've gotten lots and lots of nice comments and people elsewhere. I was interviewed on national television yesterday by somebody who saw it and thought it had some value to it. So as I say, it's always my number one assignment of the year. And I think it came off reasonably well. I agree. Did you feel differently writing it this year versus past years, though, because of all of the different challenges and adversity that Purdue has a whole face this year? I think so, because while I always try to think about those messages from a Purdue standpoint and a student standpoint, this year was, to me, you couldn't give a talk at the end of this year and not center it somehow on the experience that we just went through. But I just thought that especially what our students did, the way they conducted themselves, the character that they showed, which as I've said, over and over, was the indispensable element. Yes, we did 100 other things so that everyone's education could keep moving unimpeded, but would have all gone for naught had we not had the kind of students that we did. And so to that extent, I thought it wrote itself. And then I tried to put it in the larger context that, in my opinion, too many other places, too many other people and institutions did not live up to their responsibilities. And we expect our graduates, wherever they go, to do so. Sure, and you talked a lot about taking risks and the importance of making these big decisions. And looking back, do you ever second guess your decision to fully open Purdue? Well, it ended well, so you don't have to now. I wouldn't use the word second guess, but I would say, I mean, on a daily basis, we questioned what we were doing. First thing, every morning of last semester, in the second semester, we were able to feather it back to three and then two times a week, because I don't believe in meetings for meeting's sake. But last semester, every morning, first thing, we were looking at the data, looking at where the cases were, were any of them severe. And so of course, we were fretting about that on a constant basis, knowing that, however, under control things seem to be today, we could get up tomorrow and have a different situation. And we learned a lot.  I mean, now we can look back and I've pointed out we did a number of things that we thought might help. Now we know much more and probably didn't need two miles of plexiglass. Didn't need to spend all the time we did rearranging dorm rooms and the beds. We probably cleaned and sanitized surfaces more obsessively than made any real difference. But we weren't going to leave anything to chance. And so to that extent, I'm glad we did what we did, even though some of it was probably not too important. Sure. And what was it like and how did you feel telling the world last April, Purdue is going to be fully opened and have in-person classes and activities? Apprehensive, it looked like. I felt very much it was the right thing to do if we could bring it off. I'll say it the other way around. I thought it would be a default of responsibility to just throw up our hands and say, this might not work so all 35,000 of you figure it out, take a year off or something. But of course, but that's the essence of difficult decisions. You don't know and you can't know. And if you try to wait till you think you know everything, it's usually way too late for whatever call that was to succeed. What do you think you were most worried about leading up to the 2020-2021 school year? The factors that would have caused us to call a halt or make a U-turn, there were three in Disha that I think I worried about or thought about the most. First and foremost was severity. I don't know why others didn't do this, but early on I asked our medical advisors, construct for us a simple measure of how ill people are. Because if any significant number of either students or staff were getting really dangerously ill, that would have been a trigger. And so there was a 1 to 6 little simple system they created, 1A symptomatic all the way up to 6, better go to the hospital. Only 2% of all the cases we had all year ever got past level three or something like that. So that was one thing that we watched very carefully and happily. We had just a tiny number, even of hospitalizations and those resolved. So then a second thing would have been if we'd run out of quarantine space. Because we knew it was essential when someone had it so transmissible to move them to a place till they weren't going to infect someone else. We never got close to that either. Again, we turned out we had many more beds for that than we thought we might. The third thing would have might need. And the third thing would have been if the local hospitals, emergency rooms, or I'm sorry, intensive care units, were overwhelmed and we had anything to do with it. It was our staff or our students. Happily that didn't happen either. Those were the three, maybe not the only three, but those were the three indicators that I probably watched the most closely. Sure. And the Boilermakers keep going video featuring you. I remember watching that during the IU Purdue game as it came on as a commercial. I turned to my husband who's an IU graduate and I was like, did you just see that? He was like, that was good. I'll admit it. I just remember feeling so proud to be a Boilermaker. Was there a certain moment that you can look back on and think of that you were the most proud of this Purdue community? Oh, I was proud throughout. I was proud of our folks for making that video. I had said to them before, an unrelated really to the pandemic, we get these slots on the Big Ten Network and occasionally somewhere else where you're able to put your institution on display for 60 seconds. I said, ours looked just like everybody else's. People standing around with beakers, huddled over a computer screen or something. I said, now there's some things that are unique about Purdue and we should emphasize those. Well, it came this last year and we really did have something that was different. So many of our peers didn't go to school at all or everybody was stuck in their room all the time or no in-person classes and so forth. And so I thought they did a really great job of showing others what, if you were here, you saw our students, our faculty, this institution coming together to achieve. Yeah, absolutely.  Well, we've all learned so much. I mean, we could fill another podcast with what we've learned about how to mix online instruction with in-person about work that does pretty darn well on a remote basis or partially remote. There are all sorts of lessons like that that I hope we learn and adapt. It'll make people's work family lives better. It'll be environmentally better if fewer people are driving and parking and so forth. To me, it was not a surprise that this university, and I'm going to go back to the students first and foremost, did come together and achieve what it did. Not a big surprise, but certainly gratifying to see one's impressions or positive suspicions borne out. Yeah, and I talked to Dr. Ramirez. And he just had so much praise for the students, and I know I've heard you speak as well on that. Is there anything that, looking back, maybe you would have done differently? Oh, sure. I mean, I've already mentioned several things we did that maybe the dollars we spent, the effort we spent, could have been directed at something else. I hope we won't have to go through it again. But there's quite a playbook, and we've tried to be very honest with ourselves and others about things that were valuable, others that weren't. But yeah, I think the one thing I would emphasize is we probably should have been more attentive, maybe aggressive than we were. Too many courses were started on in-person or were listed as in-person, and then somehow changed to online. And too many students were disappointed that that happened. And I'd heard from some students to whom it happened maybe three or four courses. And that wasn't a good thing. If we ever had to go through it again, I think we would be much more alert to that, try to prevent that happening wherever possible. Sure. And what did you miss the most about the school year last year? Was it? Oh, contact with the students. We all have our own way of doing things, but mine for all these years been be out a lot, and funning around, going to events. The gym, a huge change for me. I used to go three and four times a week to the co-rec. And that couldn't do that. Had to swap for something much more limited. Did you get a peloton? No, I borrowed a couple of aerobic machines, not a peloton, and some weights. But I'll say the range and variety of the workout has shrunk some, but I'm still sort of in routine maintenance at this point. So you recently released a video encouraging students to get their vaccines. What do you think needs to change in order for things to open up even more in the fall? It'll depend more than anything else on the rate of vaccination of particular students, but also our staff. And as you know, we've opted for a, I'll call it a free choice approach. And people have the option to just stay with testing, regular testing, which we all went through this last year. But we are strongly encouraging. We think all the evidence supports, hopefully, as close to universal vaccination as we can get to on this campus. And the higher that rate is, the closer to the world we knew we can approach and still know that we're not endangering anybody. Yeah, and now we kind of see the light at the end of the tunnel. How do you think higher education emerges after this huge pandemic? First of all, we hope we see the light. Yes, true. One of the imponderables is viruses are the ultimate survival machine. And they adapt and they mutate as we know. And so we're watching all that. But I agree that from everything we can see, including we've now seen some of these variants here and they're not worse so far. So let's hope that this path of improvement that we've been on continues. Everybody wants that. Higher ed will be different whenever we're past this. Because first of all, it has caused even more people to question its value. Now, we've talked here at Purdue now for about a decade about higher education at the highest proven value.  And now people are already asking, I think, the right questions. How much education will I, or my child, garner at institution A versus B per dollar spent? And now I think that's all become much more important. Clearly, we will be asked to and need to respond to the interest of students in a more flexible education. And so we're already headed this direction, but we better head there fast if we want to succeed in the new environment. So that means even more opportunities for work experience, internships, and study abroad. And we're already offering a lot of three-year degrees, which I think may become more popular with students who want to get on with it more affordably and get out and start earning their way in the world. So we're going to have to be open to these kind of ideas, and I hope, a step ahead of other schools in providing them. Right.  What else are you looking forward to come fall 2021? How about a national basketball championship? I'd love to hear that. We're going to be good. I'm looking forward to seeing and I hope discovering that Purdue at record size is still maintaining its quality, its rigor, a good personal individual experience for students, even though we're going to have more by far than we've ever had. Most of your viewers, I hope, will know that for the fourth year out of the last five, it's record attendance. First 10,000-person class, it appears in Purdue history, and that's probably anything I've seen, the biggest in the Big 10. Now, that's wonderful that this university is attracting students from everywhere, great students. But it imposes a great responsibility on us to maintain and keep enhancing it. The quality of each person's experience gets harder as the scale gets bigger. But a lot of our faculty and others here talk about excellence at scale. We've got the biggest engineering school in the world's top five or 10. And I don't want to say it's easy. It's a lot easier to have excellence in a very small, if you're dealing with small numbers. So I'm looking forward to that, seeing us meet that very positive challenge as a community. And you mentioned, obviously, the planning for next year is in full swing. And you recently relaunched your presidential lecture series. Is there anyone that you'd love to see come to Purdue and speak in that? I don't think we're quite ready to announce the series yet, but I've already recruited two or three, and that's probably what we'll have in a given semester. I'll just say that in any job, a person should ask herself, himself, where can I add some values? There's something I can do that is, in any way, different or additive to what's already going on. Well, one of those things seemed to me was that because of past lives I had led, I might be able to sometimes say, increase the intellectual traffic flow through campus and recruit people to come here who might not otherwise. And so I hope we can do that again. I think it could be a real part of our students and faculty and our neighboring community positive experience. And so yeah, I look forward to getting that rolling again, and I hope in person, as we were accustomed to before. Yeah, I'm looking forward to it as well. And you mentioned your past life. You've said your time at Eli Lilly was some of the best experience ahead of becoming the governor of Indiana. And I've had the pleasure of speaking with people from Purdue Polytechnic High School, the data mine here at Purdue, and they've just been raving about the partnerships with Eli Lilly. What does that mean to you to see your past life and your current life kind of combine? Well, obviously, anything involving Lilly has special. I have special affection for, frankly, I've told a lot of students here who ask about career planning. I laugh and talk about what a lousy career planner I was, and just life planned me. I thought I would finish my working days at Eli Lilly and company. I believed in our mission with saving lives, improving lives, advancing science. The people there were invariably of great character and mutually supportive of each other. It was just a wonderful place to work. And that corporation was a great community. So of course, I'm very interested in that any time we interact with them, they are year in, year out. Let's face it. We're good for Lilly, because for decades now, and still the case, they're one of our top. They hire more graduates here than almost any company. It's no surprise. They've been great, as we say, corporate citizens for as long as that company's been there. And so the only surprise would be if they weren't directly involved in helping us with our high schools or the programs here on campus. And meanwhile, now the whole world has learned how fortunate we are to have great pharmaceutical companies, great science that goes on there. They've just saved who knows how many lives. Yeah, absolutely. And you said on the Business and Beyond podcast recently that there's a piece of you that's glad that you didn't run for president, because you would have never ended up here at Purdue. What have the past eight years meant to you? Well, not a piece of me, all of me. True, you're all here. I've told some of our folks, people, when they bring that up, I say things like, at this point in life, I'm not taking the demotion. I wouldn't have missed this for the world. I didn't see it coming. As I said, I thought I'd finish my working days at that great company we just discussed. Life changed not once, but three times since. And this change was my favorite in many respects. No, I mean, it's been a huge learning experience for me. And I hope we've contributed some things to advancing the university's interest. But I can't imagine anything else I might have done being more fulfilling than the time we've been able to spend at Purdue. I graduated in 2012, so I just missed you. But I remember hearing that and just thinking that was amazing. So let's get into some fun things. Well, this has been fun. You mean we would have more fun than that? So it wouldn't be Indiana if we didn't talk about the Indianapolis 500. Yeah. Do you plan on going to the race? Oh, yeah. Do you have seats, or? Well, I've been to a lot of. Well, full disclosure, I have been involved with previously the Holman Corporation, and now the Penske Entertainment, which is this marvelous development of this great, great person. Roger Penske, now I've gotten to know a little bit. He's everything that he was reported to be dynamo in his 80s and just done great things there and everywhere else he's been in business. So yes, I'll be there as I have been over and over. I've, on that shelf over there, you can see a picture of me. I was a big booster of auto racing, especially in my last job in particular, and even before that. As far as I know, I'm the only person from elected office who's ever been the official starter of the race. It was 2012. Nice. Graduation year, scary, by the way. Because you were in the car? Well, I've done that. No, I mean, I was, I waved the green flag. And those cars are roaring faster. And a lot of wind up there. And when I say scary, I say, you know, I don't know if anybody's going to see this flag, but I'll tell you what's not going to happen. It's not going to wind up in the first turn, because I'd never live it down. That was a fabulous opportunity. And you know, I don't know when anyone will see this conversation we're having, but this year's race, it's always one of the biggest sporting events in the year. It's always the biggest spectator event of any kind in the world. But this year, it's not just a sporting event. If it goes off well, let's hope and pray it does. I mean, it is a big, it's a worldwide event on the way back to normalcy. This will be the most people in one place for any reason, I think, since the pandemic started. And so it's, in a way, it's a medical event, as well as the greatest spectacle in racing. Right. Do you have any favorites for drivers? Are you betting on anyone? Well, those are two different questions. I won't have any bets then. Ed Carpenter, if you just make me pick somebody, he's a great person and he's homegrown, got a route for the home team. We've got a number of teams and drivers from Indiana, but Ed is one. So yeah, yeah, I'll be watching the 20 car with special interest. Awesome. And are you going to slow down at all this summer, or does your pace keep going? There's some natural. I've told friends from other times, I'd never had a seasonal job before. This isn't quite that, but clearly, when the campus population drops from 40,000 students to several thousand, it's different. And there's plenty to keep us busy. And planning for this fall, just as it was last summer, there are some additional features that my predecessors and I in earlier years didn't have to think about as you saw August coming. Sure, absolutely. Is there anything else you'd like to tell our listeners? I just hope that, I think, Boilermakers have always had a special affinity and pride for this place, and that's not, that would be a natural thing. I'm sure people at every school feel that way, but this has been measured. And there is a statistically significant difference, has been people's sense of loyalty and so forth. I've always assigned a lot of that to the fact that this is a place of upward mobility. That's why land grant schools were created, but I think it produced cases especially pronounced. I say all the time, I've now had a chance for a decade to meet so many tremendous Purdue alums. Almost none of them came from privilege. This is the place where the young woman or man from the farm or the small town or the inner city came from. And then over and over by the now hundreds of thousands were launched on great lives. And so we've always been proud, and I think that's part of it. I've talked to so many people, and it starts the same. For me, it started at Purdue. I owe it to Purdue, if not for Purdue. It's the thing I love the very most about this place, as you can see from my sniffles. And I hope the last year added a layer on top of that for all the reasons we just discussed. Absolutely. Yeah, and I think anyone like we talked about with that Boilermakers keep going. It's emotional, and it'll get you every time. Well, I do think it reflects. It's like the couch. Somebody said, well, that's a Purdue thing, tinkering around and inventing something that works. And I'd like to think that our navigating through this difficult circumstance expressed something that's always been there about this place. Absolutely. Well, we so appreciate your time and your energy, and we love talking to you. And it was all fun, all of it. I agree.


that's over 65 if married, filing, joint or blind. We'll get into that basically later. But that's our little worksheet. So I'm going to put this, let's make this black and white, home tab font group. I'll make this black, white, I'll center it. And then I'm just going to, I'm just going to put tables around this home tab font group. Let's put borders around that. Let's make this black and white, home tab font group, black, white. There we have it. So that means that that when I look at the standard deduction, I'm going to change this based on the table. Now we can try to automate this, you could say, well, if it's single, it'll populate automatically. But I kind of like the physical necessity of saying equals, and then going down here and saying, okay, what's going on here? It's the single status that helps you to determine that's helping me determine, okay, it's a single file, or that's why it's at the 13, 850. And that ties out into our worksheet here, where it's the 13, 850. So then, so then that when we when we say, okay, well, which one is it going to take between these two, we want to take the the larger of the itemized or this one. So this will be a data input in here. And this will be a formula. This is a formula we can use called max, meaning take the biggest one. That's what that formula means pretty basic formula, but sometimes it's hard to remember because it's not used as often, but take the max of those two. And so it takes the 13, the 13, 850 in this case, I should probably pull that down here. And then say this is going to be so so then I could just say this is the greater of a said just say great tour of and then I'll indent that two times home tab alignment, indent that two times just so we have a subtotal pulled it inside and then we pulled basically the result down here, which is taking the greater of these two. So that's going to give us then our that's going to be equal to then our man, it did a formula enter. And then that's going to give us our taxable income. So taxable income, which is going to be equal to the 100,000 minus the greater of the itemized or standard deductions. So that's the 86 150, which ties into the 86 150 here. So that's the bottom of like the income statement, which we usually do our data input and are focused on with our data input side of things. The second half of the calculation is the tax. So we'll go back on over and say, Okay, let's say we're going to take that times, in essence, I'm going to say times with an x times the the tax rate, let's call this the average tax rate. Now notice we don't actually multiply times an average tax rate. What we do is we we apply those tax brackets. So but I'm so I'm going to back into this number, I'm going to let the software now do the calculation. So I'm going to say this equals the tax before credits and other taxes.