2014s408 Swift Playgrounds

 >> Hi.

 Welcome to Swift Playgrounds.

  I'm Rick Ballard and with me today is my colleague  Connor Wakamo.

  We're both Engineers in the Xcode Team  and we've been working hard to bring Playgrounds to life.

  We introduced Playgrounds to the world Monday morning  and you saw a little bit more  about them Monday afternoon and yesterday.

  Well, today we're going to go into a lot more depth.

  We're going to start out today with some conceptual background,  what Playgrounds actually are and what you can use them for.

  And then we'll show you examples of how to use Playgrounds  for learning, exploration, and visualization  of the results of your code.

  We'll show you how you can use your own custom resources  with your Playgrounds, and how to use Playgrounds  for algorithm development and development  of other separable pieces of code.

  We'll introduce the XCPlayground framework  which includes some really powerful utilities  that you can use to enhance your Playgrounds.

  And we'll show you how you can develop your own Custom Quick  Looks, so that you can visualize your own classes the same way  you visualize the classes that come with the frameworks.

  Next, we'll show you a great demo  of how awesome Playgrounds are for developing custom views  and in any other kind of custom drawing  and we'll show you how you can use your own asynchronous code  with Playgrounds.

  Finally, we'll finish up today with a little bit  about the limitations that Playgrounds have today.

  So what exactly are Playgrounds?  Playgrounds are a new type of document introduced in Xcode   and they're actually a file wrapper containing a few  useful things.

  First of all is your Swift code.

  The code that would be run and the result are,  and generate results to display automatically every time you  edit your Playground file.

  Swift Playgrounds also can contain a folder  of embedded resources which are made available to your code  or your Playground can reference resources elsewhere  on your system you want to make available.

  Finally, your Playground can contain a timeline full  of timeline items that provide useful visualization  of your results beyond what you see in the sidebar.

  When you first open a Playground,  we show the Playground Editor with your Swift code on the left  and the results sidebar on the right showing the result  of every expression in your code.

  Every time you edit your source, we rerun your Playground source  from the top to the bottom and present the new results  from that run in the sidebar.

  This is the basic editor mode.

  But if you go into the assistant editor mode we'll show the  Timeline Assistant by default which allows you  to visualize your results in more detail.

  For example, you can display the value history  from a line in your code.

  In this case, since it's a numeric value,  we'll draw a graph of that value over time  since it was iterated multiple times in a loop.

  If you're looking for console output like that from Print Man,  you'll also find that in the Timeline Assistant.

  There are a couple other useful things you,  I want to call out here.

  In the lower right hand corner, there's a time-stepper.

  And this controls how long your Playground will continue to run  after the top of a source is finished  if you're using live views or indefinite execution.

  And I'll explain what both of those are a little later on.

  There's also a slider which allows you to go back in time  and view results in the timeline from a specific point  in your Playground execution.

  So here, you can see we're viewing a numeric result  from partway through the Playground execution.

  But you'll find this is very useful with live views  as it allows you to scrub back through the recording  of that view and see exactly what your animation was doing  at a specific point in time.

  So that's what Playgrounds are.

  Let's talk a little bit about what you can use them for.

  We think your first great use  of Playgrounds is going to be learning.

  We've introduced a brand new language for you to learn  and we think the best way to get started is just to open  up a Playground and dive in and play around.

  Our documentation also includes a special interactive Playground  called the Swift Tour.

  This allows you to see documentation  and Playground Editor side by side in the same editor.

  So you can read about how to do something and try it  out right there without leaving the editor.

  Finally, we think Playgrounds are a fantastic way for people  to learn how to program in the first place.

  Beginners don't have to learn how to configure a project  and target and build and run and debug.

  They can just type code into a Playground Editor  and immediately see the results.

  So if you know anyone who wants to learn how to program,  we encourage you to suggest trying it in a Playground.

  We think Playgrounds are also going to be  in indispensable tool in your toolbox  for everyday code development.

  If you're developing an algorithm  or any other separable chunk of code,  you should consider starting it on a Playground,  working on it there until you have it how you want it,  and then dragging that code into your project  for use in your application.

  Any sort of drawing code you want to do is also great  in a Playground because you can immediately see the visual  result of what your code is doing.

  And every time you change your code,  you can immediately see how that affects the visual result.

  Finally, processing code like value transformers or a sequence  of image filters are great in Playgrounds  because you can visualize the result at every step  of the transformation process.

  And when you change something, you can see how  that change ripples through all your results.

  We think you'll find  that Playgrounds are fertile ground for experimentation.

  And in particular, any time you're trying  to learn some new API, you should try it  out on a Playground because you can immediately see how it works  and what results it gives you.

  You don't need a project, you don't need to build and run.

  You just open up even a standalone Playground document,  type in your code, and see what happens.

  I'm sure all of you have many a time gone  to create a new project from the application template,  and gone to find applicationDidFinishLaunching,  just to put a line of code and to try some API.

  Oh, and then you probably have to NSLog it too  so you can see what happened.

  You don't have to do that anymore.

  Now you can just open up a Playground and try  out the API you want to try.

  In fact, we'd recommend you consider keeping a Playground  in your doc at all times for quick access.

  So anytime you want  to try something it's right there at your fingertips.

  So with all that said, let's dive in and take a look  in an actual Playground.

  To do that, I'm going to invite my colleague Connor up on stage.

  >> Thank you, Rick.

  Hello everyone.

  My name is Connor.

  I'm an Engineer on the Xcode Team.

  And today I'll be talking to you about how you can work  with Playgrounds as well as some of the things  which we think Playgrounds will be really great for.

  Now, Rick has already covered many  of the basic concepts behind Playgrounds.

  And so I think really the best way to show you how to work  with Playgrounds is actually just  by jumping straight into a demo.

  So, let's go ahead and do that.

  So here I am at the demo machine and I'm just going  to go ahead and launch Xcode.

  Now you'll notice here that on the Welcome window  for Xcode we've added this brand new "Get started  with a Playground" button.

  It's that way we want to make it really easy for you  to just get started with one.

  So I'll just click on that.

  We'll create a Playground and I'll just give it a name  and a place to save it.

  So "MyPlayground" is fine and putting  on the desktop is fine as well.

  So let's say create, and then we have here our Playground itself.

  So, you notice that we're importing Cocoa,  so we have full access to the Cocoa APIs.

  And then we are also creating a string  and we're assigning the value, "Hello,  Playground" to that string.

  You'll notice that in the result sidebar we're seeing the result  of that.

  So in this case we're seeing the string, "Hello, Playground".

  So OK.

 So that's kind of the basic idea.

  Let's try something with numbers.

  So let's say, for i in 0 to 10, let's just say, i times i.

  You see there that we execute the code  and we're getting an indicator in the result sidebar  that we've executed that code 10 times.

  So, OK, let's try bumping that up to 100.

  We'll let it run and we'll see there  that we immediately get an indication  that this code has executed 100 times.

  Now, knowing that is very useful information  but sometimes you actually want to see the value there.

  And we have support for that as well.

  So OK, I'll just hover over this result, and you'll see  that we're highlighting the line of code  with which it is associated.

  And we're also showing this button here.

  That's called the Value History button.

  And if I go ahead and click on it,  we'll open up the assistant editor into the timeline mode.

  This is the place where you can see results over time as well  as a place for you to store results which you  like to see persistently.

  So in this case, we're showing the graph for i times i.

  And we've seen this, you know, this nice little curve here.

  So OK, so that's kind of the basics of using the timeline  and calculating numbers.

  Let's try something a little bit more interesting.

  Let's go ahead and do something with AppKit.

  So let's first start up by creating a color.

  So you let color equals NSColor.

blueColor.

  You'll see there that we're now showing  in the result sidebar a color swatch indicating what the color  is as well as indicators of all of the components  which make up that color.

  So I can, you know, take this color  and let's create another attributed string using it.

  So let's say, let attrStr equals NSAttributedString.

  And we'll pass it in the string in an attributes dictionary.

  So we'll use the string we already have  and we'll create a dictionary.

  So we'll say NSForegroundColorAttributeName  and we'll pass it the color we have.

  And then I'll say, NSFontAttributeName,  I'll just pass it a font.

  So I'll say, NSFont, systemFontOfSize  and then let's go to something fairly big, so I'll just put  in 42, see what that looks like.

  So, OK.

 So here, you notice  that we're getting a result for this as well.

  You're seeing that we're showing the plain text representation  of this, as well as an icon indicating  that it is an attributed string.

  Now, that's great.

  You know, we know that this code is executed.

  But I really want to see what the actual value is there.

  See how the attributed string looks itself  and we support that as well.

  So I can just hover over the result and in addition  to the Value History button,  you'll see that we have a Quick Look button.

  And so if I go ahead and click on that we'll show a Quick Look  of that value to show you the full representation of it  as it was created in the Playground source.

  So, OK, that's colors and strings.

  Let's try something with images.

  Let's actually start  up by creating an array of image names.

  So I'll say, let imageNames equals,  we'll put in an array there and, I know it's something to do  with like NSImageNameUser or accounts  or something in that line.

  So I'm just going to create an array with imageNames  that I think it could be, the ImageNameUser,  NameUserAccounts, NSImageNameUserGroup.

  It's OK.

 We run the code and you notice  that we now have an array of strings.

  We actually want to see an array of images  and that's very easy to do.

  I can just say something like,  let images equals imageNames.

map.

  I'll pass it a trailing closure to just say, NSImage named,  pass it the positional argument $0.

  And you'll notice there that we're now seeing that this line  of code executed 4 times.

  And so, basically we can see that,  you know, OK, that makes sense.

  We're executing this line of code 3 times  for the trailing closure itself.

  Then we're executing it once for the assignment to images.

  Actually, I only want to see the images array itself  and we have a nice little trick for doing that in a Playground.

  You just go ahead and put the thing that you want  to see on a line by itself.

  So there you see, you know, we've put images there,  we rerun the code, and we're seeing the images array.

  I can Quick Look that and I can see, "Oh, you know,  here's the image that I'm looking for.

"  And so, I'll just get that image and say,  let image equals images at 0.

  We'll rerun it.

  I'll Quick Look to make sure it's OK and in fact, yeah,  that's the one that I'm looking for.

  Let's go ahead and put this into an image view.

  So I'll say, let imageView equal NSImageView.

  We'll pass our self a frame, so let's say NSRect.

  We'll say 0 for the origin  because we don't really care about that.

  Then we'll also say by 512 for the size.

  Now I'm going to go ahead and put this ImageView  on its own line as well.

  So I can show this result in the timeline.

  And this is a neat little way of building something up.

  You take the, you start creating the object  and then you put another line where we show it as a result.

  Anyway, I can add some code in between there  to see how it builds up over time.

  So you see here that we're starting  out with just this empty imageView, you know,  we're not seeing any interesting there.

  So let's go ahead add our image to the imageView.

  So let's say, imageView.

image equals image.

  And we'll re-execute and we'll see here now that we're  in fact showing the image there  but it's not filling the full imageView.

  It's not doing what we expect.

  That's because we haven't set up the image scaling appropriately.

  So we'll set that as well.

  Say imageScaling equals ImageScaleProportionally  UpOrDown.

 And we'll re-execute and now you'll see  that we're seeing the image at full size in the imageView.

  We're seeing what we expect.

  And it's OK.

  That's how you can work with system resources.

  But I'm sure you have many resources of your own that you'd  like to use in Playgrounds as well.

  And we support that too.

  So I'm just going to go ahead and I'm going  to show the final inspector.

  It will slide in on the right hand of my Playground.

  And you'll notice here that we're,  we have this new section called Playground Settings  which is shown whenever you're viewing a Playground document.

  You can select the platform  against which the Playground should execute.

  And, you know, OS X is what we're doing right now.

  But we also support iOS.

  And you can select a path for resources.

  This defaults to none but you can select one  if you have resources that you're interested in.

  In this case, I'm just going to say I have a folder of resources  on my desktop so I'm just going to say,  let's use the Absolute Path option.

  I can then go ahead and choose that.

  So let's say here's my resources folder, I'll choose that.

  And then once I made that choice I'm actually going to go ahead  and hide the Utilities area.

  And to access the images themselves, I just use,  you know, NSBundle API, you know, the resources show  up as resources for the main bundle.

  So I can say something like "let myImage equals NSImage, named".

  I have an image in here that's just called  "Xcode" so let's grab that.

  We'll re-execute and you'll notice  that now we're getting the image result here.

  And click, click to confirm that it's what I think it is.

  And in fact, it is, we're seeing the Xcode icon there.

  And now I'm just going to have  that imageView show the Xcode icon instead.

  So, I'll say, "imageView.

image equals myImage".

  We'll re-execute and now you're seeing this new result,  let's add it to the timeline as well.

  So you can see here that we have what we expected.

  The Xcode icon is showing up in our imageView.

  You'll probably also notice  that we're still seeing the older version here  with the user icon in the imageView.

  And that's because Playgrounds actually capture results  on every single line of execution.

  So you can do these kinds of comparisons.

  So like for instance, you know, let's look at the imageView  when we first create it.

  And it's empty.

  Then I added the user icon to there.

  And so, we see that earlier version that we saw  where it's small in the center.

  Then I set the image scaling appropriately  and it's now filling full image view.

  Finally, I updated it to use myImage and we're seeing  that it's showing the Xcode icon.

  And that's great, so that you don't have, you know, go back  and see what happened at a particular point.

  We're capturing the data for you as your Playground executes.

  So I think that about covers the basics, so let's go back  to slides and talk a little bit more about Playgrounds.

  So one of the key ideas that you saw there is  that Playgrounds will automatically execute.

  You just type in some code and you'll see the results  in a sidebar on the right.

  Additionally, you saw that we can add a value history  to the timeline.

  So here we have a line of code which executed 100 times.

  And if I hover over that result,  you'll see this Value History button.

  If I click it, we'll switch into the assistant editor  and we'll show that as a history of that value.

  Additionally, many values in the Playground have Quick Looks.

  All right.

  So in this case we have an attributed string.

  We don't see the full representation of the sidebar,  just kind of the plain text of it.

  But if I click on the Quick Look button,  we'll see the attributed string as it was created  in the Playground source.

  We support many different types  for Quick Looks in the Playground.

  We support colors, strings -- both plain text and attributed.

  We can show images, views,  in this case we'll capture a snapshot of the view  at that point in time.

  We can show arrays and dictionaries  as we'll show a structured version of the array  or dictionary, ah, like you might see  in the variables view on the debugger.

  We can show points, rects, and sizes.

  We'll kind of create a graphical representation of those.

  We can show Bézier paths, so both NSBezierPath on the Mac  and UIBezierPath on iOS.

  We can show URLs, for this we'll take the plain text of the URL  and show it in the sidebar.

  But if you Quick Look, it will show you a web view  with the contents of that URL.

  And finally, for types  if we don't have a native Quick Look representation,  we can usually get a structured view of it, again,  like you would see in the variables view in the debugger.

  So here I have an object of a class  that I created in the Playground.

  And it is, it has a couple of properties,  a foo property and a bar property.

  And you're seeing the values of those at that line  of code when it executed.

  In this demo, I also showed you how you can use your own  resources with Playgrounds.

  And this is actually fairly easy.

  So you just go ahead and show the file inspector.

  You select a location for Playground resources.

  And for this we have three options.

  We've got an Absolute Path option which basically says,  "OK, I've got this folder of resources somewhere  on my computer and I'd like to show it  and use it with the Playground.

"  We have a Relative to Playground path option.

  And this is really great  if you're checking your Playground into SCM.

  Because you can say, "Oh, you know, here's this Playground  and here's this folder of resources that's next to it,  I can set this up and then when you use other people to check  out your repository, then it will automatically be able  to use the Playground with its resources.

"  Finally, we support an Inside Playground option.

  And this is great if you're sharing  in ways other than via SCM.

  Because you can just say, "I want to store my resources  in my Playground" and you can email that out to other people  and see, when they open it, they'll be able  to see those resources immediately.

  Once you have made the selection,  to access these resources in your Playground source,  you just use things like,  NSBundle.

pathForResource ofType and NSImage named.

  The resources just show up as the resources  for the main bundle during Playground execution.

  So, now that we have the basics out of the way,  I think I'd like to start talking to you about some  of the use cases for which Playgrounds would be  really great.

  And the first of these is Experimentation.

  I'm sure that all of you out there have a folder  on your computer which looks something like this.

  It's just a bunch of Xcode projects created  from the template that are, you know, maybe 1 or 2 changes  to see how something works or to test out an idea.

  It's actually isn't that easy of a process.

  You know, you have to do many different --  you have to first choose the right project template then find  the right file in that project to edit which may be easy  or maybe not depending on which template you chose.

  You'd have to do what you're trying to do in the first place,  and that's write some code.

  Once you've written something, you then have  to build your project.

  You then run whatever you built.

  And for iOS that may involve deploying  to a simulator or to a device.

  And if you didn't get it right the first time, you'd then have  to redo this, stop in the debugger and step  through your code to figure out where things are going wrong.

  We think Playgrounds can handle this a whole lot better.

  That's because there's really only 2 steps.

  You would just, say, get started  with a Playground and write your code.

  Once you start writing your code,  we'll automatically execute it for you and show you the results  in the sidebar so you can see where things are going wrong.

  So now, I think I'd like to show you a demo  of what this looks like.

  So let's go back to the demo machine.

  So here I am.

  I'm going to go ahead and just launch Xcode again.

  And this time I'm going to create an iOS-based Playground.

  So I'll say, File, New File, and I'll say, iOS Playground.

  And I want to actually test  out how the UITableViewCell style API works.

  So, I'm just going to call and create this Playground  and call it TestTableViewCell.

  Save it to the desktop, and OK.

  So, here we have our iOS Playground.

  It's, you know, importing UIKit, but otherwise, it's the same,  we're just creating a string and assigning it to a variable.

  So, if I want to use a UITableViewCell style,  I need a UITableViewCell.

  And the best way to show that is with a UITableView.

  In order to get those cells  into my UITableView, I need a data source.

  So, let's just go ahead and implement a data source.

  So I'll say "class DataSource".

  We'll inherit from NSObject and we'll conform  to the UITableViewDataSource protocol.

  Notice now that we're getting an issue here and that's  because the DataSource we've created does not actually  conform to UITableViewDataSource.

  And, you know, that's expected.

  We haven't actually implemented any methods yet.

  So, I'm actually going to jump to the declaration  of UITableViewDataSource by command-option-clicking on it.

  We see that we then open the assistant editor.

  And instead of showing you UITableView.

h,  we're going to show you a Swift version of that header.

  So, in this case, we're seeing, you know, here's our protocol.

  We're seeing that we need to implement these two methods.

  And so, OK, I'm just going to take this one, this first one  to tell the TableView the number of rows per section.

  I'm going to copy and paste it in here.

  And then I'm just going to start things out, return 1 from this.

  So, OK.

 So that's the number of rows.

  Let's also provide the cell.

  And OK, let's just go ahead and create our UITableViewCell.

  Let's say let cell equals UITableViewCell.

  I need to fix this typo.

  Here, we'll say the style, we'll just say the default style.

  And then for the reuseIdentifier,  we aren't actually going to be reusing these cells  so we can just pass nil for this parameter.

  And OK, so there we have our cell.

  Let's go ahead and configure it.

  So, I can say something like cell.

textLabel.

text equals Text.

  OK.

 So that's the text label.

  We'll see what that looks like.

  UITableViewCell may also have a detail text label.

  But that's not guaranteed to be the case.

  So I'm going to explicitly handle the fact  that it's an optional.

  So, I can say something like  "if let detailTextLabel equals cell.

DetailTextLabel".

  And so, if the code inside of this "if" executes,  then we'll know that we have a detailTextLabel.

  So, I can say something like,  detailTextLabel.

text equals Detail Text,  and we know that this is safe.

  We're not going to accidentally try to assign a property to nil.

  So now that we've configured our UITableViewCell,  I can just go ahead and return that.

  You can see now that we no longer have an issue  in our Playground.

  But we're also not getting any results in the sidebar.

  That's because we haven't actually instantiated our  data source.

  So, I'll just say something like DataSource equals DataSource  and then I can, you know, I'll just create a TableView  and tell it to use our DataSource.

  So, let tableView equals UITableView.

  We'll pass it a frame so, CGRect.

  Again, we don't care about the origin.

  I'll pass 320 for the width,  and for the height we just need enough to be able  to show all the cells we care about.

  So, I'll just say something like 240.

  Finally, we'll pass a style of Plain.

  We'll then tell the tableView to use our DataSource.

  And then, we will tell the tableView to reload data.

  Let that Playground execute.

  And once it's finished executing, we'll be able  to see the tableView we've created.

  So, I'm going to just go ahead and add this to the timeline.

  We can see here that we've created our tableView, you know,  we're seeing the cell that we want,  with the text that we want.

  So, OK.

 So that, you know, gets us up and running.

  But actually I want to see the styles  for all the styles that we have.

  So, I'm going to jump back to the declaration  of UITableViewCell style.

  And you can see here that there are 4 options.

  So I'm going to change this 1 to a 4, so if 4 rows.

  Instead of always passing the default style,  I'm going to conditionalize it based on the row  that we're currently at.

  So, I'll say let row equals IndexPath.

row.

  And I'll say something like let style equals  UITableViewCellStyle.

fromRaw.

  I'll pass the row.

  This fromRaw will convert the UITable, the raw row integer  into a UITableViewCell style optional.

  And we confirm that by using quick help and we can say that,  "Oh, yes in fact, this style is an optional  UITableViewCell style.

"  If we were to pass this directly here,  we would get an error as you can see here.

  We need to explicitly handle the fact that this could be nil.

  You know, the UITableViewCell initializer doesn't expect that.

  So, let's go ahead and check that.

  So we'll say, if we have a style, let's unwrap it,  otherwise you just use the default style.

  It's OK.

 Now that we've handled that,  let the Playground re-execute and let's jump back  to the timeline using the jump bar.

  And once it's re-executed, we'll notice here  that we're now seeing all the different UITableViewCell styles  in our tableView.

  And so now, I have a Playground which I can, you know,  share with my co-workers or just keep it as a reference  for myself to see what each UITableViewCell style  looks like.

  Let's go back to slides now.

  So that showed you how great Playgrounds are  for experimentation.

  You just get started with an idea,  write some code, and see how it works.

  And now I'd like to invite Rick back on stage to talk  about another great idea we have for Playgrounds  and that's Algorithm Development.

  Rick?  >> Thanks, Connor.

  Developing algorithms and any other separable pieces of code  in a Playground is a great way to go.

  And so to show you that, I'm going to dive right into a demo.

  So what we're going to do today is implement insertion sort,  a fairly straightforward sort.

  We're going to create a brand new Playground to do that.

  So I'll just say get started with a Playground,  and we'll call the Playground InsertionSort  and save it on the desktop.

  If you're not familiar with insertion sort,  imagine that you have a hand of cards and you want to put them  in order with the lowest values in the left  and the highest values on the right.

  One way you might do that is, start with the second  to leftmost card and compare its value to the leftmost card.

  If it's less, you'd swap the position  of the two cards in your hand.

  You'd then look at the third to leftmost card and compare it  to the second to leftmost.

  If it's less, you'd swap it, compare it to the leftmost card,  swap it if needed, and go on doing this for every card  in your hand until every card had reached the correct,  sorted position.

  When you're done, your hand will be in order.

  So, let's implement that in a Playground.

  To start with, we need some random data  that we're going to sort.

  So, I'm going to go ahead and I'm going  to declare an array of data.

  I'm going to use var because this needs  to be a mutable array, so I can add to it and sort it.

  And we'll just make an empty array of ints to start with.

  And I could say for i in 0 through 20,  because maybe I want 20 data points.

  I can say data.

append to add a new element.

  And let's use the arc4random function  to generate a random number.

  That doesn't return a Swift Int, so we're going  to cast it explicitly to a Swift Int.

  And we'll modulus it by 100 to get a number between 0 and 99.

  So if I look at data here,  you can see I have a result here on the right.

  Here's an array of what look like pretty random numbers.

  You'll also notice if I edit the Playground source again it  reruns and I get a different array of random numbers.

  Ah, OK, so that's great.

  Well, it's nice to be able to generate random data  but I probably don't want it to change  on me every time I edit the Playground source  because that might make it hard to develop my algorithm.

  So, let's grab this random data and use it every time.

  To do that, I'm going to click over the result sidebar  and use command-A to select this data, command-C to copy it,  and then I'm just going to paste this in here as array literal.

  And now I can work off the same random data every time.

  OK.

 So, let's start implementing our algorithm.

  The first thing we need is a function  to swap two points of data in our array.

  There actually is a built-in function called swap  for this already.

  But for the sake of argument, we'll implement it ourselves.

  So, I'm going to say func.

  I'll call mine exchange.

  You know, we're going to make this a generic because, well,  we have an array of ints.

  Our insertion sort should be able to work on any type.

  So, any type at least as long as it's comparable.

  One element can be compared as greater  than or less than another.

  So, we'll mostly work on comparable types here,  the exchange function can work on any type  because we just are swapping types.

  So this is an exchange using a type D.

  And it's going to take an array of T and two indexes  which we're going to exchange in the array.

  So, the simplest way to exchange these objects is to assign one  to a temporary variable, assign the second to the first,  and assign the temporary variable to the second.

  So, we can say let temp equals data of i.

  Data of i equals data of j.

  And data of j equals temp.

  OK.

 I think we've implemented this correctly  but let's try it and find out.

  I can say exchange, pass my data array  and we'll say exchange the 0th element with the second element.

  And then we'll take a look at our array when we're done.

  So, before, element 0 was 12, and element 2 was 15,  now element 0 is and element 2 is 12.

  So, it looks like exchange works properly.

  OK.

 The next thing we need is a function to, given an index,  look at the data point of that index,  compare it to the data point to its left; if it's less,  exchange them and keep comparing and exchanging  until it reaches the correct position in the array.

  So, let's call this function swapLeft.

  Again, it's a generic but this time we need  to actually do a comparison.

  So, we're going to say our type D is comparable and we're going  to pass an array of T and an index of the data point we want  to start swapping left.

  OK.

 So, let's implement this, we're going to start  with our index and go back to position 1,  not 0 because there's nothing to the left of 0 to swap.

  So, I'm going to say for i in, and, you know,  I could do a range from 1 to index  but what I really want is index to 1.

  So I'm going to reverse the range with reverse 1.

  3 dots makes it a fully closed range  which means it will go all the way to index.

  So, since I'm reversing this, it goes from index and ends at 1.

  And for each of these data points, I'm just going to say  if data of i is less than data of i minus 1,  exchange data i and i minus 1.

  OK.

 If it's not less than data of i minus 1,  it must have reached the correct sort of position  in the array, so we can stop there.

  So, let's say else break.

  OK.

 Let's try this function out.

  I'm going to go ahead and say swapLeft, pass data,  and let's pass element 1, 2, 3, 4, 5, 6.

  Let's pass element 6 left.

  Oops! And look at our data.

  And you can see the has moved all the way  from the 6th position to the beginning of the array  and everything's been moved to the right.

  So it looks like this function is working great too.

  OK.

 The last thing we need is to actually implement the sort,  so this should be pretty simple.

  We'll call our function isort,  works again on type T that is comparable.

  And we can just pass an array of T  and it will sort the whole array.

  To do this, I'm just going to say for i in 1 (we're starting  at 1 because there's nothing to the left of 0 to sort to)  to data.

count, swapLeft, data and i.

  So, let's try it out, isort data.

  And we'll look our data array when we're done.

  And you can see it did a whole bunch of assignments up here.

  And now here's our final array and it looks  like this is in sorted order.

  So, we've correctly implemented insertion sort.

  So, this is great for a simple algorithm like insertion sort.

  That wasn't too hard.

  But you know if I was doing something more complicated,  it might be nice to have more visibility  into exactly what's going on here.

  So, let's look at how we might visualize our results  in more detail.

  Well to start out with, let's draw a graph of the results  of the data at the beginning.

  To do that, I'm just going to say for x in data (to iterate  through every data point) and just print out x.

  And so, you'll see there are 20 data points here.

  So this line executed 20 times.

  And if I click on the Value History button,  I get a nice graph here showing my data at the beginning and,  boy, that does look random.

  OK.

 So, now I want to try to print  out another graph every time swapLeft is called,  so I can see what's happening to the graph  over iterations of swapLeft.

  And I could put this "for" statement in the end  of swapLeft again and show the Value History.

  But again, in Value History Timeline item for given,  a line is going to show all the data from that line.

  So, each time swapLeft is called,  its data would be appended to the same graph.

  That's not what I want.

  I want a new graph, every time it's called.

  So to do that, we're going to need a new tool in our toolbox.

  I'm going to go back to slides and show you that.

  With Playgrounds, we're shipping a new framework called  XCPlayground and it contains some very useful utilities  for enhancing your Playgrounds.

  Right now, we have API for manually capturing values  to display in timeline items, showing your views live  and extending execution for asynchronous code.

  Right now, we're going to use the API  for manually capturing values.

  That API is called XCPCaptureValue.

  It's a function that takes an identifier, which is a string,  and your value, which is of any type.

  When you pass it -- your value -- it will take that value  and put it in a timeline item for you.

  So, the identifier that you pass it identifies what timeline item  you want that value to go to.

  If you call this function on different lines  but pass the same identifier,  the values from those different lines will go  to the same timeline item.

  Conversely, and what we want here, if you have one line  that calls XCPCaptureValue but it's called multiple times  with different identifiers  and it passes those different identifiers,  that one line can generate multiple different timeline  items (or grabs, in our case).

  That identifier is also shown as the name of the timeline item  so you can easily see what data is what.

  The value pass can be anything, because it's a generic  but it helps if it's a type of value that we know how  to Quick Look appropriately.

  So, let's go back and give this a shot.

  So to start out with, I need to import XCPlayground  to make this API available and I'm going to go ahead  and define a new function.

  I'll call it visualize and it's a generic.

  And it will take an array of type T and I'm going to use this  "for" loop in it, so I'll just indent that  and close the function.

  But instead of just printing out x, what we want  to do is capture that value.

  So, I'll call XCPCaptureValue.

  I need an identifier, so let's add one to our function.

  So, identifier is a string and we could pass  that identifier, and our value is x.

  OK.

 So let's try this function out and visualize the data  at the start of our sort and we'll label it Start  as the identifier just so we know what's what.

  And here you can see it ran and here's our data at the start.

  So that's a good start.

  So now, we're going to go ahead and visualize our data  after every iteration of swapLeft.

  So, I can call visualize, I'll pass data as it is  after this iteration of swapLeft.

  And for our identifier, let's label it after the iteration,  the number of times that swapLeft is called,  which is the index parameter.

  And so, I'm going to let this run now.

  And you can see that it's generated multiple graphs  labeled after the iteration that we're on.

  So, now we can just scroll through here  and see what's happening to our data over time as swapLeft runs  and the sort completes.

  You can see it looks like our data is getting sorted piece  by piece.

  And so, at the end, we have a nicely-sorted array.

  So there, we can easily visualize exactly what's going  on with our algorithm.

  We think you'll find this very, very useful.

  OK.

 Let's move on to another example.

  I've got a heap Playground I made here earlier.

  And it's got this HeapGrapher class at the top  which I'll explain in a moment.

  But the meat of this class is my heap class which,  if you're not familiar with a heap, a heap is a type  of balanced binary tree where the value  of every node is greater than or equal  to the value of its children.

  Heaps are often used to implement priority queues,  because it's very efficient  to remove the highest priority item, that's the top  of the tree, and it's also efficient to insert new items  into the correct position of the tree for their priority.

  We're implementing our heap with an underlying array  to represent the tree.

  And in our array, the tree noted index i has children  at indexes i times and i times 2 plus 1.

  So you can see down here  at the bottom we've got some random data  that we seeded ourselves with.

  And we've created a new heap with that data.

  And we "heapified the heap," which is to say, put that data  into correctly heap-sorted order.

  On the right, in the results sidebar,  you can see our default treatment  of this custom class is to show the name of the class  and show its properties.

  In this case, it has one property which is  that heap array and here it is before it's been heapified,  when it's not a correct heap.

  And here it is after it's been heapified,  when it's purportedly a correct heap.

  But you know, it's really hard to tell looking  at this array whether that's a correct heap.

  This array represents a tree and, you know,  not so good at visualizing, "Hh, well, here's I,  and here's i times 2, and yeah, that's less.

.

.

"  Wouldn't it be much better if I could just visualize this  as a tree everywhere my heap is referenced  to my Playground source?  So let's see how to do that.

  In order to visualize my own custom class,  we're going to implement Custom Quick Look Support  for this class.

  Our Custom Quick Look Support allows you to add Quick Looks  for subclasses of NSObject only (right now).

  And to do it, you implement the debugQuickLookObject method  which takes no parameters  and returns any object as an optional.

  And you're going to return the value that you want  to represent your object as its Quick Look.

  So, right now, that value (the values  that we support here) are colors, strings (both plain  and attributed), images, and Bézier paths.

  So, for your Custom Quick Looks you can use any of these types.

  So, let's try it out.

  OK.

 So I mentioned before I had a little HeapGrapher class  that I wrote.

  That's a little class that knows how to take an array and draw it  as a tree, so we're going to use that.

  We'll implement our debugQuickLookObject method.

  It takes any, or returns any object as an optional  and we're just going to create one of our HeapGraphers.

  And this HeapGrapher knows how to generate an NSImage  which is one of the Custom Quick Look types, supported types.

  So, we're just going to return the image it generates  with g.

graphHeap and pass self.

heaparray.

  And now, when this runs, instead  of showing the default representation for our class,  it shows our custom Quick Look representation,  which is an image.

  And so when I click the Quick Look button,  you can see here it's drawing my heap as a tree.

  This is before it's been heapified when you can see,  for example, 78 is less than 89.

  So this is not a correct heap.

  But if I Quick Look it after it's been heapified,  I can now go, oh great, is greater than 86 and 89,  86 is greater than 84 and 79, and so on and so forth,  and I can really easily visually verify  that this is a correct heap.

  So that's how you can Quick Look your own classes in Playgrounds  and we think you'll find that very useful.

  All right.

  Next, we'd like to move on to showing you how great it is  to do Custom View Development  and other drawing development in Playground.

  And to do that, I'm going to hand it over to Connor.

  >> Thank you, Rick.

  Another great use case we think Playgrounds will be used  for is Custom View Development.

  And that's because you can just start writing some code  and see the actual view as it's being drawn  and as you're starting to build up your drawing code.

  So for this I have a goal.

  I want to take this Playground icon  and add some animation to it.

  The icon that we have is really great.

  It conveys the playfulness of Playgrounds.

  But unlike Playgrounds themselves, it's static.

  There's nothing dynamic about it.

  And so, I'm going to try to add animation to this.

  And what better way to do it than when  in a Playground itself?  So, let's jump over to the demo.

  So OK, here I'm going to go ahead and open up a Playground  that I've already started.

  So, OK.

 So here we've got a Playground.

  We've got our subclass of NSView called PlaygroundIconView.

  It has a few layers.

  It's got these three instance, er, these three instance methods  which actually do the setup of those layers.

  You see that they're unimplemented right now  and we'll come back to that in a moment.

  I also have an extension of NSColor which defines a couple  of colors for the Playground icon itself.

  I then have a helper function to convert an NSBezierPath  to a CGPath for use with CAShapeLayer.

  Finally, I just go ahead and create an instance  of my PlaygroundIconView.

  And then, I put it on a separate line  so I can add some stuff later.

  Let's go ahead and show that in the timeline.

  So, OK.

 So you'll see now  that we've just got ourselves an empty view here.

  So yes, we have an empty view here.

  We actually just now need to go ahead  and implement these setup functions.

  So let's go ahead and do that.

  So we'll start out by creating the path  for the background layer.

  So you can see here we're creating NSBezierPath  and we can Quick Look it to make sure it looks right.

  And in fact, yeah, that looks more or less  like the Playground icon.

  So let's tell, let's setup our layer.

  So OK, now we're setting up the layer.

  You can see here in the timeline  that we're now drawing the layer where, you know.

.

.

  We have the background, we've got the little border there,  and so, OK, we've got our background set up.

  Let's also do the seesaw base and we'll do the same thing.

  We'll create a path for that.

  And we'll let it execute and we'll see here,  let's Quick Look, make sure.

.

.

  Yeah, that looks more or less like the little base  that we have for the play- .

.

.

for the seesaw.

  So let's set up the layer itself as well.

  And there, we just make that change  and immediately get the feedback of seeing what that looks  like when drawn in our view.

  Let's also do the seesaw layer.

  I've got some code here to set that up as well.

  You see here that we're just, you know, have a closure  which will create the child layer itself.

  We then create a couple of layers for the children  on each side of the seesaw, and then we set up the bench itself  and then add those layers to our seesaw layer.

  So, OK.

 So now we've got ourselves something  that looks kind of like the Playground icon.

  But like the icon itself, it's not animating.

  So let's go ahead and add support for animation  to our PlaygroundIconView.

  I have a snippet for that as well.

  And so, let's walk through what this is doing.

  I define a constant for the maximum angle of the seesaw.

  I've, you know, worked through this and I think pi  over 12 is about right.

  I also have a property for the current angle of the seesaw  after any pending animation is finished.

  And then have a property which determines whether  or not it should be animating.

  It starts out as false but we have this code here  which executes whenever this is set to say, "Well,  if the animation state has changed and we're told  to animate, then just start animating depending  on the current angle of the seesaw.

"  I then have this helper method  for actually performing the animation itself.

  So we just, you know, go ahead and create a CABasicAnimation,  set a couple of values, set our timing function  to match what a seesaw would actually look like.

  Set the duration to what was passed in which defaults  to 1-1/2 seconds, but can be customized depending  on the angle of the seesaw.

  We then add the animation to our seesaw layer.

  We set the underlying transform property of that seesaw layer,  so that once the animation completes it looks correct.

  And then we update our current seesaw angle  property accordingly.

  Finally, we have, uh, we implement the "animationDidStop,  finished" delegate callback.

  Or basically say that if we finished  and we're still supposed to still be animating,  then just go ahead and animate to the opposite angle  of what we currently are at.

  So, OK.

 Let's go ahead and tell this view to start animating.

  So we'll do that and you'll notice that after it reruns,  we seeing the view update it's look, you know,  so we see that it tilted over to the side.

  We're not seeing the animation itself.

  And for that, we're going to need some help  from the XCPlayground framework.

  So, let's switch back the slides  to see what that could look like.

  So the second piece of functionality  which the XCPlayground framework provides is the ability  to show live views in the timeline.

  And you do that by calling this XCPShowView function.

  It takes an identifier and the view that you want to show.

  After calling it, we'll show the view live while the Playground  executes and then we'll record frames  as the Playground executes  so you can play them back once execution finishes.

  The identifier you pass to this function must be unique inside  of the Playground.

  That's because this is how we refer  to the live view internally in Xcode.

  And it is also what we'd show as the title  for the live view in the timeline.

  The view pass must also not have a superview.

  This is because we will add it to our own view hierarchy  and it would generally not produce the results you're  looking for.

  So with this in our toolbox, let's jump back to the demo  and see how it's used.

  So I'm going to go ahead and just go ahead  and import XCPlayground.

  And then down here, instead of just having this view item,  I'm going to remove that from the timeline.

  I'm going to say something like XCPShowView  and pass an identifier.

  It can be anything as long as it's unique.

  So I'll say Playground Icon View.

  And then I'll pass the view that we've created.

  So, we'll just let that re-execute.

  And you see there that in the timeline,  we're showing the view live as it's animating.

  You-all also probably noticed this little timeout field  down here.

  And that lets us specify the amount of time  which we'll let the Playground continue executing  after we reach the end of execution of the top of a code.

  Now, it defaults to 30 seconds but I'm going to adjust this  down since I know my animation only takes  about a second and a half.

  So I'll do 10 seconds to get a few times around.

  After we edit that, we'll rerun it.

  And so that's great, you know, we see it running there.

  And I'd like to show how you can integrate XCPShowView  with the XCPCaptureValue API we mentioned earlier.

  And so, what I'm going to do, I'm going to capture the angle  of the seesaw, or of the left edge  of the seesaw as we're animating.

  So here, I'm just going to say XCPCaptureValue.

  I'll pass Left Seesaw Position and I'll just pass   because we know at this point that it's,  you know, it's flat on there.

  Then you can take this and I'm going to put it in our  "animationDidStop, finished" callback.

  Now I'm going to just pass the negative currentSeesawAngle.

  That's just because that's what we need to do in order  to get the left position of the seesaw.

  That is how the angle works out for the transform.

  So you see here that as we're executing,  we're getting the graph kind of building up over time.

  And then once execution finishes,  the graph will snap back into place and kind  of show you the best view of the data that it collected.

  It's OK.

 You probably also noticed this slider  became active.

  And so, I can just go ahead and take that  and drag it through here.

  And you'll notice that we're updating the graph at the bottom  but we're also showing you the animation, you know,  as it went through in time.

  So this is, you know, a fairly basic animation  and it's doing what we expected but, you know,  if you had something more complex and you want  to just kind of take a look at just a small portion  of your animation, you could do that as well.

  And I can also do something like, you know,  click on one of these points.

  So I can click there.

  We can see it, you know, that the two things are in sync.

  I click there.

  It updates the point.

  I can use the arrow keys to go through the graph's points  and see that, OK, yeah, you know,  we're doing what we expect it to do.

  And so, that's how you can show live views in the timeline  with the XCPlayground framework.

  Let's go back to the slides now.

  Now, I'd like to talk to you  about how you can use asynchronous code  in your Playgrounds.

  You got a little taste of this in the demo before.

  But I'd like to go into a little bit more detail now.

  The third piece of functionality  which the XCPlayground framework provides is the ability  to extend execution.

  By default, execution terminates once all top-level code  has executed.

  XCPlayground, though, provides API  for extending execution indefinitely.

  That's this XCPSetExecutionShould  ContinueIndefinitely function.

  You should know that this is actually not quite indefinite.

  The execution time is controlled by the timeline's timeout  which defaults to 30 seconds.

  Additionally, execution will be terminated  if you edit the Playground while it's running.

  This is so that we can show you up to date results rather  than let, leaving you a stale results while we wait  for an earlier execution to finish.

  Additionally, as you saw on the last demo, you know,  we didn't actually call this function,  but we saw that execution continued  after we reached the end of top-level code.

  That's because XCPShowView implicitly  calls XCPSetExecutionShould  ContinueIndefinitely.

  You should just think about this as if nothing  in the Playground source has told Xcode  that the Playground used to stay alive,  then the Playground will stop executing once we reach the end  of top-level code.

  So now, I'd like to show you a quick demo of what it's  like to use asynchronous code in Playgrounds.

  So here I am back here and I have a Playground  which uses asynchronous code.

  We create, uh, we have our session delegate  which is an NSURLSessionDelegate.

  It has a few callbacks.

  And then we also just, you know,  create an instance of our delegate.

  We created an NSURLSession.

  And then create a data task to download the contents  of the Apple home page.

  We then tell the data task to resume.

  And you noticed that, you know,  the Playground itself has executed  but we're not receiving any results up here.

  And if I open up the assistant editor, you'll notice  that we haven't received any console output even though they  were clearly logging here that we've received some bytes.

  And this is because nothing  in the Playground has told the Playground  that it should continue executing.

  So we call task.

resume, we resume the task and then as soon  as that finishes, we hit the end of top-level code  and the Playground just stops executing.

  Let's go ahead and say import XCPlayground.

  And then we can say XCPSetExecution  ShouldContinue, XCPSetExecutionShould  ContinueIndefinitely.

  This takes a Bool but that defaults to true,  so you typically don't need to pass anything there.

  And I won't do that here.

  You'll now notice that, you know, we were receiving results  from here and we're also seeing the console output  that we expect in the timeline.

  So OK, that's how you use asynchronous code  in Playgrounds.

  Let's go back to slides now.

  There are a few alternatives but we really think  that you should typically use XCPSetExecutionShould  ContinueIndefinitely when you're trying  to use asynchronous code in Playgrounds.

  If that won't work for you though,  you can use other methods for waiting  for asynchronous operations to finish.

  Basically, you just need to make sure you don't reach the end  of top-level code before your operation completes.

  Before we leave today, I'd like to talk to you a little bit  about some of the limitations we have with Playgrounds.

  First off, you should not use performance, uh,  Playgrounds for any performance testing.

  That's because the logging of results  in the Playground will generally dominate the runtime,  not your actual code.

  This means that the performance will be dependent on the number  of lines of code executed, not the actual performance  of whatever it is you are developing.

  And that's not necessarily what you'd expect.

  Instead we'd suggest that you use the XCTest framework  to create performance tests in a test bundle  where you can get more accurate results.

  We have a session later this week called Testing in Xcode   which will go into this in more detail.

  There are few more limitations with Playgrounds.

  Playgrounds cannot be used for things  which require user interaction.

  So we have great support for showing live views  but you can only see them, you can't touch them.

  We also do not support using Playgrounds for anything  which require custom entitlements.

  For iOS Playgrounds, we only support executing  against the simulator.

  So anything which requires a device will not be supported  with Playgrounds.

  And finally, we do not support using your own app  or framework code in a Playground unless it's something  that you can just copy and paste into the Playground source.

  Basically, you can only use things in the standard library,  in the SDK, or that's in the Playground source itself.

  You can get around some of these limitations by using the REPL.

  The REPL is the command line interface to Swift  and it works this way because the REPL can actually execute  in your own process.

  You just stop at a breakpoint, and then at the LLDB prompt,  you execute the REPL command and you'll just be dropped  down right into the Swift REPL.

  Playgrounds though provide a richer experience than the REPL.

  And that's because we will automatically execute your code  from a known state.

  That means, you know, you make a single edit to a line and then,  you know, we just rerun it from 0.

  Whereas with the REPL, if you wanted to make an edit  to something earlier in the source that you had entered,  you have to, you know, get the process back  into the state then, you know, reenter the REPL,  retype everything making that one change  to see how it affects things.

  Playgrounds also supports some of these higher level futures  like Quick Looks and a timeline which we do not support, uh,  which the REPL does not support.

  If you'd like to learn more about the REPL,  you can go to the Introduction to LLDB and the Swift REPL talk.

  And we'll go into much more detail about how the REPL works.

  In summary, we think Playgrounds are a great way to play  with Swift, with Cocoa and with Cocoa Touch.

  We think you can use them for things like learning,  exploration and visualization and frankly probably tons  of things which we haven't even thought of yet.

  The XCPlayground framework provides APIs  for using your Playgrounds for more advanced things.

  So you can do things like manually capture values  with the XCPCaptureValue API.

  You can show live views in the timeline by calling XCPShowView.

  And then you can also extend execution  for asynchronous operations with the XCPSetExecutionShould  ContinueIndefinitely function.

  Finally, we'd really like to just encourage you to go out  and give Playgrounds a try.

  I think, you know, they're really approachable  and if you just sit down with them  for a little bit you'll find a number of great ways  to integrate them into your development process.

  For more information, you can contact our Developer Tools  Evangelist, Dave DeLong.

  We also have some information about Playgrounds  in the Source Editor Help for Xcode 6.

  You can also ask questions about Playgrounds  on the Apple Developer Forums.

  We have several related sessions about Swift this week.

  So there was an Introduction to Swift session yesterday,  which you can catch on the video.

  We also have an Intermediate Swift session later  this afternoon.

  There's also an Advanced Swift session tomorrow  which you'll be able to see.

  We had an Integrating Swift  with Objective-C session earlier this morning  which you can catch on video.

  And we also have a Swift Interoperability  in Depth session later this afternoon.

  Finally, if you'd like to learn more about the Swift REPL,  you can go to the Introduction to LLDB  and the Swift REPL session.

  Thank you all for coming  and I hope you have a great week here at WWDC.

  


标题SpringBoot智能在线预约挂号系统研究AI更换标题第1章引言介绍智能在线预约挂号系统的研究背景、意义、国内外研究现状及论文创新点。1.1研究背景与意义阐述智能在线预约挂号系统对提升医疗服务效率的重要性。1.2国内外研究现状分析国内外智能在线预约挂号系统的研究与应用情况。1.3研究方法及创新点概述本文采用的技术路线、研究方法及主要创新点。第2章相关理论总结智能在线预约挂号系统相关理论,包括系统架构、开发技术等。2.1系统架构设计理论介绍系统架构设计的基本原则和常用方法。2.2SpringBoot开发框架理论阐述SpringBoot框架的特点、优势及其在系统开发中的应用。2.3数据库设计与管理理论介绍数据库设计原则、数据模型及数据库管理系统。2.4网络安全与数据保护理论讨论网络安全威胁、数据保护技术及其在系统中的应用。第3章SpringBoot智能在线预约挂号系统设计详细介绍系统的设计方案,包括功能模块划分、数据库设计等。3.1系统功能模块设计划分系统功能模块,如用户管理、挂号管理、医生排班等。3.2数据库设计与实现设计数据库表结构,确定字段类型、主键及外键关系。3.3用户界面设计设计用户友好的界面,提升用户体验。3.4系统安全设计阐述系统安全策略,包括用户认证、数据加密等。第4章系统实现与测试介绍系统的实现过程,包括编码、测试及优化等。4.1系统编码实现采用SpringBoot框架进行系统编码实现。4.2系统测试方法介绍系统测试的方法、步骤及测试用例设计。4.3系统性能测试与分析对系统进行性能测试,分析测试结果并提出优化建议。4.4系统优化与改进根据测试结果对系统进行优化和改进,提升系统性能。第5章研究结果呈现系统实现后的效果,包括功能实现、性能提升等。5.1系统功能实现效果展示系统各功能模块的实现效果,如挂号成功界面等。5.2系统性能提升效果对比优化前后的系统性能
在金融行业中,对信用风险的判断是核心环节之一,其结果对机构的信贷政策和风险控制策略有直接影响。本文将围绕如何借助机器学习方法,尤其是Sklearn工具包,建立用于判断信用状况的预测系统。文中将涵盖逻辑回归、支持向量机等常见方法,并通过实际操作流程进行说明。 一、机器学习基本概念 机器学习属于人工智能的子领域,其基本理念是通过数据自动学习规律,而非依赖人工设定规则。在信贷分析中,该技术可用于挖掘历史数据中的潜在规律,进而对未来的信用表现进行预测。 二、Sklearn工具包概述 Sklearn(Scikit-learn)是Python语言中广泛使用的机器学习模块,提供多种数据处理和建模功能。它简化了数据清洗、特征提取、模型构建、验证与优化等流程,是数据科学项目中的常用工具。 三、逻辑回归模型 逻辑回归是一种常用于分类任务的线性模型,特别适用于二类问题。在信用评估中,该模型可用于判断借款人是否可能违约。其通过逻辑函数将输出映射为0到1之间的概率值,从而表示违约的可能性。 四、支持向量机模型 支持向量机是一种用于监督学习的算法,适用于数据维度高、样本量小的情况。在信用分析中,该方法能够通过寻找最佳分割面,区分违约与非违约客户。通过选用不同核函数,可应对复杂的非线性关系,提升预测精度。 五、数据预处理步骤 在建模前,需对原始数据进行清理与转换,包括处理缺失值、识别异常点、标准化数值、筛选有效特征等。对于信用评分,常见的输入变量包括收入水平、负债比例、信用历史记录、职业稳定性等。预处理有助于减少噪声干扰,增强模型的适应性。 六、模型构建与验证 借助Sklearn,可以将数据集划分为训练集和测试集,并通过交叉验证调整参数以提升模型性能。常用评估指标包括准确率、召回率、F1值以及AUC-ROC曲线。在处理不平衡数据时,更应关注模型的召回率与特异性。 七、集成学习方法 为提升模型预测能力,可采用集成策略,如结合多个模型的预测结果。这有助于降低单一模型的偏差与方差,增强整体预测的稳定性与准确性。 综上,基于机器学习的信用评估系统可通过Sklearn中的多种算法,结合合理的数据处理与模型优化,实现对借款人信用状况的精准判断。在实际应用中,需持续调整模型以适应市场变化,保障预测结果的长期有效性。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值