13.5 C
Canberra
Friday, September 20, 2024

Meet my new Junior Developer: ChatGPT


I’ve been enjoying round with ChatGPT for just a few days now, that I used to be capable of create an account. After all I needed to have it generate some limericks, some poems and responses to emails. However essentially the most burning query on my thoughts is that this: will AI take my job?

I discovered that ChatGPT has numerous syntax and conceptual data about Swift and SwiftUI. So I needed to place it to the check to see how good it will be in fulfilling my requests. I used to be taking up the position of the mentor and ChatGPT was mainly a pupil that took my unique request and refined it over a number of iterations till I ended up with an exquisite easy answer.

For a present venture I wanted a view that shows a circle however I didn’t wish to draw it however as a substitute use a CAShapeLayer and a property that will replace the colour of the form. So I had in my thoughts already an thought how I might do it, now the query was, how would I switch this psychological image from my thoughts to the AI’s “thoughts”.

Me: Create a UIKit view that makes use of CAShapeLayer to show a crammed circle

ChatGPT: Right here is an instance of learn how to create a UIKit view with a crammed circle displayed utilizing a CAShapeLayer in Swift:

import UIKit

class CircleView: UIView {

    override func draw(_ rect: CGRect) {
        let circleLayer = CAShapeLayer()
        let circlePath = UIBezierPath(arcCenter: CGPoint(x: rect.measurement.width / 2, y: rect.measurement.peak / 2), radius: rect.measurement.width / 2, startAngle: 0.0, endAngle: CGFloat.pi * 2, clockwise: true)
        circleLayer.path = circlePath.cgPath
        circleLayer.fillColor = UIColor.crimson.cgColor
        layer.addSublayer(circleLayer)
    }
}

I instantly observed a number of issues right here.

At this level the end result was in high quality lower than most responses I might see on Stack Overflow. The sport was on!

Me: That is nonsense as a result of it will add a brand new sublayer each time that the draw perform is being known as!

ChatGPT: I apologize for that mistake. Right here is an up to date instance that solely provides the CAShapeLayer as soon as:

import UIKit

class CircleView: UIView {
  
    override init(body: CGRect) {
        tremendous.init(body: body)
        setupCircle()
    }
  
    required init?(coder aDecoder: NSCoder) {
        tremendous.init(coder: aDecoder)
        setupCircle()
    }
  
    personal func setupCircle() {
        let circleLayer = CAShapeLayer()
        let circlePath = UIBezierPath(arcCenter: CGPoint(x: bounds.measurement.width / 2, y: bounds.measurement.peak / 2), radius: bounds.measurement.width / 2, startAngle: 0.0, endAngle: CGFloat.pi * 2, clockwise: true)
        circleLayer.path = circlePath.cgPath
        circleLayer.fillColor = UIColor.crimson.cgColor
        layer.addSublayer(circleLayer)
    }
}

It moved the creation of the form layer right into a setup perform which was known as from each inits. The one with body is used from code, the one with decoder is used when loading the view from a XIB or storyboard. This was an sudden side-benefit.

I observed although that this wouldn’t replace the trail when the bounds of the view would change.

Me: It additionally must replace the circle path when the bounds of the view change.

ChatGPT: Right here’s an up to date model of the code that updates the circle path when the bounds of the view change:

import UIKit

class CircleView: UIView {
  
    personal let circleLayer = CAShapeLayer()
  
    override init(body: CGRect) {
        tremendous.init(body: body)
        setupCircle()
    }
  
    required init?(coder aDecoder: NSCoder) {
        tremendous.init(coder: aDecoder)
        setupCircle()
    }
  
    override func layoutSubviews() {
        tremendous.layoutSubviews()
        updateCirclePath()
    }
  
    personal func setupCircle() {
        layer.addSublayer(circleLayer)
        updateCirclePath()
    }
  
    personal func updateCirclePath() {
        let circlePath = UIBezierPath(arcCenter: CGPoint(x: bounds.measurement.width / 2, y: bounds.measurement.peak / 2), radius: bounds.measurement.width / 2, startAngle: 0.0, endAngle: CGFloat.pi * 2, clockwise: true)
        circleLayer.path = circlePath.cgPath
        circleLayer.fillColor = UIColor.crimson.cgColor
    }
}

Attention-grabbing! It additionally is aware of that layoutSubviews is a superb place to do one thing when structure adjustments. Subsequent to the setup perform it additionally added an perform that updates the form.

These profitable refinements emboldened me. How about making the fill colour be configurable from exterior the view by way of a property? Additionally, whereas is technically right to attract a circle by way of an arc bezier path, that solely provides me an overview.

Me: Exchange the arc bezier path with one for an oval that additionally will get full of the UIColor set within the fillColor property.

ChatGPT: Right here’s an up to date model of the code that attracts an oval form as a substitute of a circle and fills it with the colour set within the fillColor property:

import UIKit

class OvalView: UIView {
  
    personal let ovalLayer = CAShapeLayer()
  
    override init(body: CGRect) {
        tremendous.init(body: body)
        setupOval()
    }
  
    required init?(coder aDecoder: NSCoder) {
        tremendous.init(coder: aDecoder)
        setupOval()
    }
  
    override func layoutSubviews() {
        tremendous.layoutSubviews()
        updateOvalPath()
    }
  
    personal func setupOval() {
        layer.addSublayer(ovalLayer)
        updateOvalPath()
    }
  
    personal func updateOvalPath() {
        let ovalPath = UIBezierPath(ovalIn: bounds)
        ovalLayer.path = ovalPath.cgPath
        ovalLayer.fillColor = UIColor.crimson.cgColor
    }
}

Hm, it says that it did it, particularly including a fillColor property, however that’s nowhere to be discovered. So I attempted to say it in a greater method.

Me: Don’t arduous code the fillColor, however make it a property of the view that updates the overLayer when set.

ChatGPT: Right here’s an up to date model of the code the place the fill colour just isn’t hardcoded and may be set as a property of the view:

import UIKit

class OvalView: UIView {
  
    personal let ovalLayer = CAShapeLayer()
  
    var fillColor: UIColor = UIColor.crimson {
        didSet {
            updateOvalPath()
        }
    }
  
    override init(body: CGRect) {
        tremendous.init(body: body)
        setupOval()
    }
  
    required init?(coder aDecoder: NSCoder) {
        tremendous.init(coder: aDecoder)
        setupOval()
    }
  
    override func layoutSubviews() {
        tremendous.layoutSubviews()
        updateOvalPath()
    }
  
    personal func setupOval() {
        layer.addSublayer(ovalLayer)
        updateOvalPath()
    }
  
    personal func updateOvalPath() {
        let ovalPath = UIBezierPath(ovalIn: bounds)
        ovalLayer.path = ovalPath.cgPath
        ovalLayer.fillColor = fillColor.cgColor
    }
}

I had mistyped “overLayer”, however ChatGPT nonetheless understood my request and executed it flawlessly. This was already fairly good, however an knowledgeable programmer wouldn’t be glad with this and maintain sharpening the end result till it shines.

Me: Separate the replace of the fill colour from updating the form path. The trail ought to solely be up to date when the bounds change and the colour solely when the property adjustments.

ChatGPT: Right here’s an up to date model of the code the place the fill colour and the form path are separated, and the form path is simply up to date when the bounds change:

import UIKit

class OvalView: UIView {
  
    personal let ovalLayer = CAShapeLayer()
  
    var fillColor: UIColor = UIColor.crimson {
        didSet {
            ovalLayer.fillColor = fillColor.cgColor
        }
    }
  
    override init(body: CGRect) {
        tremendous.init(body: body)
        setupOval()
    }
  
    required init?(coder aDecoder: NSCoder) {
        tremendous.init(coder: aDecoder)
        setupOval()
    }
  
    override func layoutSubviews() {
        tremendous.layoutSubviews()
        updateOvalPath()
    }
  
    personal func setupOval() {
        layer.addSublayer(ovalLayer)
        updateOvalPath()
    }
  
    personal func updateOvalPath() {
        let ovalPath = UIBezierPath(ovalIn: bounds)
        ovalLayer.path = ovalPath.cgPath
    }
}

Ha! I noticed one other mistake! This fashion the fill colour wouldn’t stay the default and solely be up to date if the property is modified.

Me: That is lacking the preliminary setting of the fill colour.

ChatGPT: Right here’s an up to date model of the code that units the preliminary worth of the fillColor property:

import UIKit

class OvalView: UIView {
  
    personal let ovalLayer = CAShapeLayer()
  
    var fillColor: UIColor = UIColor.crimson {
        didSet {
            ovalLayer.fillColor = fillColor.cgColor
        }
    }
  
    override init(body: CGRect) {
        tremendous.init(body: body)
        setupOval()
    }
  
    required init?(coder aDecoder: NSCoder) {
        tremendous.init(coder: aDecoder)
        setupOval()
    }
  
    override func layoutSubviews() {
        tremendous.layoutSubviews()
        updateOvalPath()
    }
  
    personal func setupOval() {
        layer.addSublayer(ovalLayer)
        updateOvalPath()
        ovalLayer.fillColor = fillColor.cgColor
    }
  
    personal func updateOvalPath() {
        let ovalPath = UIBezierPath(ovalIn: bounds)
        ovalLayer.path = ovalPath.cgPath
    }
}

That’s right. Now we’re had been at a degree the place I used to be not so sure as a result of I don’t create CAShapeLayers day-after-day. We have to set the form layers body in some way, don’t we?

Me: I consider that this code is lacking an replace for the body of the sublayer.

ChatGPT: Right here’s an up to date model of the code that units the body of the ovalLayer sublayer:

import UIKit

class OvalView: UIView {
  
    personal let ovalLayer = CAShapeLayer()
  
    var fillColor: UIColor = UIColor.crimson {
        didSet {
            ovalLayer.fillColor = fillColor.cgColor
        }
    }
  
    override init(body: CGRect) {
        tremendous.init(body: body)
        setupOval()
    }
  
    required init?(coder aDecoder: NSCoder) {
        tremendous.init(coder: aDecoder)
        setupOval()
    }
  
    override func layoutSubviews() {
        tremendous.layoutSubviews()
        updateOvalPath()
    }
  
    personal func setupOval() {
        layer.addSublayer(ovalLayer)
        updateOvalPath()
        ovalLayer.fillColor = fillColor.cgColor
    }
  
    personal func updateOvalPath() {
        ovalLayer.body = bounds
        let ovalPath = UIBezierPath(ovalIn: bounds)
        ovalLayer.path = ovalPath.cgPath
    }
}

Yeah that appears higher, if we set the body each time layoutSubviews is named then that ought to work. At this level I had a thought that I needed to Senior-Programmer’splain to the poor and overwhelmed AI…

Me: layoutSubviews might be the incorrect place to replace the layer body and oval path as a result of that belongs to the view structure circulate, however there’s a separate structure circulate for layers. put it there.

ChatGPT, unflinchingly: Right here’s an up to date model of the code the place the body of the ovalLayer and the oval path are up to date within the layoutSublayers perform as a substitute of layoutSubviews:

import UIKit

class OvalView: UIView {
  
    personal let ovalLayer = CAShapeLayer()
  
    var fillColor: UIColor = UIColor.crimson {
        didSet {
            ovalLayer.fillColor = fillColor.cgColor
        }
    }
  
    override init(body: CGRect) {
        tremendous.init(body: body)
        setupOval()
    }
  
    required init?(coder aDecoder: NSCoder) {
        tremendous.init(coder: aDecoder)
        setupOval()
    }
  
    override func layoutSublayers(of layer: CALayer) {
        tremendous.layoutSublayers(of: layer)
        updateOvalPath()
    }
  
    personal func setupOval() {
        layer.addSublayer(ovalLayer)
        ovalLayer.fillColor = fillColor.cgColor
    }
  
    personal func updateOvalPath() {
        ovalLayer.body = bounds
        let ovalPath = UIBezierPath(ovalIn: bounds)
        ovalLayer.path = ovalPath.cgPath
    }
}

Impressed, once more! It is aware of about layoutSublayers.

Then I believed some extra. I used to be fearful in regards to the circle not being correctly up to date in UIView animations. When you set a layer body in layoutSubviews then the contents jumps to the brand new location and measurement with out animation, as a result of UIView properties are implicitly animated, however layer properties will not be.

And why do we want the fundamental CALayer in any respect, after we could make the form layer be the view’s major layer? Ha! Now I knew learn how to stump the AI!

Me: It could even be higher to make the form layer the primary layer of the view as a substitute of organising a separate sublayer for it.

ChatGPT: Right here’s an up to date model of the code the place the CAShapeLayer is about as the primary layer of the OvalView as a substitute of a separate sublayer:

import UIKit

class OvalView: UIView {
  
    var fillColor: UIColor = UIColor.crimson {
        didSet {
            layer.fillColor = fillColor.cgColor
        }
    }
  
    override init(body: CGRect) {
        tremendous.init(body: body)
        setupOval()
    }
  
    required init?(coder aDecoder: NSCoder) {
        tremendous.init(coder: aDecoder)
        setupOval()
    }
  
    override func layoutSublayers(of layer: CALayer) {
        tremendous.layoutSublayers(of: layer)
        updateOvalPath()
    }
  
    personal func setupOval() {
        layer.fillColor = fillColor.cgColor
        layer.masksToBounds = true
    }
  
    personal func updateOvalPath() {
        layer.body = bounds
        layer.cornerRadius = bounds.width / 2
    }
}

Gotcha! Gone is the form layer solely to get replaced by setting the layer’s cornerRadius to half of the width of the view. And an expertly inserted masksToBounds makes this work.

Good attempt, however let me let you know what’s incorrect with this:

Me: That doesn’t work when the view just isn’t sq.. I would like you to create the layer for the view by way of returning CAShapeLayer because the layerClass of the view.

ChatGPT blushing: Inside server error

Was it one thing I stated? No, most likely not. ChatGPT’s servers get overloaded often. After I pressed the “Regenerate Response” button I bought a correct response:

ChatGPT: Right here’s an up to date model of the code the place CAShapeLayer is returned because the layer class for the OvalView:

import UIKit

class OvalView: UIView {
  
    var fillColor: UIColor = UIColor.crimson {
        didSet {
            layer.fillColor = fillColor.cgColor
        }
    }
  
    override class var layerClass: AnyClass {
        return CAShapeLayer.self
    }
  
    override func layoutSubviews() {
        tremendous.layoutSubviews()
        updateOvalPath()
    }
  
    personal func updateOvalPath() {
        let ovalPath = UIBezierPath(ovalIn: bounds)
        (layer as! CAShapeLayer).path = ovalPath.cgPath
        layer.fillColor = fillColor.cgColor
    }
}

Good! We’re again in enterprise. I pasted this code into Xcode solely to discover a syntax error I had missed from solely glancing at it.

Me: That can produce a syntax error as a result of the layer within the fillColor setter just isn’t recognized to be a CAShapeLayer to the compiler. It’s good to solid it to at least one.

ChatGPT: Right here’s an up to date model of the code that casts the layer property to a CAShapeLayer within the fill colour setter:

import UIKit

class OvalView: UIView {
  
    var fillColor: UIColor = UIColor.crimson {
        didSet {
            (layer as! CAShapeLayer).fillColor = fillColor.cgColor
        }
    }
  
    override class var layerClass: AnyClass {
        return CAShapeLayer.self
    }
  
    override func layoutSubviews() {
        tremendous.layoutSubviews()
        updateOvalPath()
    }
  
    personal func updateOvalPath() {
        let ovalPath = UIBezierPath(ovalIn: bounds)
        (layer as! CAShapeLayer).path = ovalPath.cgPath
        (layer as! CAShapeLayer).fillColor = fillColor.cgColor
    }
}

Technically right now, however nonetheless in want of polish.

Me: Refactor these `(layer as! CAShapeLayer)` right into a property

ChatGPT: Right here’s an up to date model of the code that makes use of a computed property to keep away from casting layer to CAShapeLayer a number of instances:

import UIKit

class OvalView: UIView {
  
    var fillColor: UIColor = UIColor.crimson {
        didSet {
            shapeLayer.fillColor = fillColor.cgColor
        }
    }
  
    personal var shapeLayer: CAShapeLayer {
        return layer as! CAShapeLayer
    }
  
    override class var layerClass: AnyClass {
        return CAShapeLayer.self
    }
  
    override func layoutSubviews() {
        tremendous.layoutSubviews()
        updateOvalPath()
    }
  
    personal func updateOvalPath() {
        let ovalPath = UIBezierPath(ovalIn: bounds)
        shapeLayer.path = ovalPath.cgPath
        shapeLayer.fillColor = fillColor.cgColor
    }
}

Ah, now good… now we have a brand new shapeLayer property that power casts the layer property right into a CAShapeLayer. I put the code into my venture, it compiled with out challenge and displayed the crimson circles I lusted for as requested.

Me: Thanks, that’s one of the best reply for my preliminary query.

ChatGPT: You’re welcome! I’m glad I may assist. When you’ve got any extra questions, be at liberty to ask!

Analysis

Much like tales the place ChatGPT sat college exams with unhealthy however passing grades it additionally performs across the junior degree for software program builders. It is ready to produce the right end result if an skilled developer has the endurance and abilities to guided it over a number of iterations.

It does require numerous hand-holding. Inputting your necessities by way of chat requires that you know the way to specific all these ideas in a method that the AI can parse. I do have numerous expertise coaching Junior Engineers and a decade of programming UIKit taught me learn how to put issues that they are often understood.

I might have spent a fraction of the time if I had simply coded this view like I envisioned it from the beginning. However the level of this change is to not show that I’m higher at programming than ChatGPT. It’s to show that Chat GPT is extra succesful than discovering pattern code on the Web. It’s not even net search on sterioids. It’s clearly way more than that as a result of it may possibly perceive ideas and synthesize a end result from that together with making refinements that an knowledgeable consumer is guiding it to do.

This can be a first information level. There was none earlier than it as a result of public entry to ChatGPT was solely activated just a few days in the past. So it’s superb that one thing is feasible in the present day that wasn’t attainable earlier than.

The Future

Within the least I would really like ChatGPT constructed into Xcode: as a solution to write new code. And I don’t imply dictating code, however talking in ideas like proven above. How about having this in Xcode? “Hello Xcode, I want a brand new view that does this and that”. If that had been extra streamlined and quicker that will instantly be helpful. Particularly as a result of it additionally improves your individual studying curve. Having to speak ideas makes you your self perceive them higher. What you train, you study!

I can see a future the place ChatGPT turns into increasingly productive to the eventual diploma of a Junior Developer. With this I imply any person who can conceptional execute the itty gritty which you, as a Senior Developer, give it path in a common imaginative and prescient you keep. Just like the captain of a ship who sees the ice bergs and is aware of the place the ship must be going, and ChatGPT is the whole crew.

Then the step after that – within the far future – is to mix ChatGPT with one thing that may perceive sketches and mockups and useful descriptions of apps. That is the place the Senior Developer brains are and can nonetheless be wanted for a very long time. To translate the shopper’s needs and designs into software program ideas.

We haven’t touched on the query what is going to occur if sooner or later all Juniors may be changed by AI. If there are not any new Juniors then there shall be no person to mature into Seniors sooner or later. Perhaps our coaching should change to give attention to mastering conceptionalizing and excessive degree idea synthesis and leaving the mundane creation of code to AI as a substitute.



Additionally revealed on Medium.


Classes: Instruments

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

[td_block_social_counter facebook="tagdiv" twitter="tagdivofficial" youtube="tagdiv" style="style8 td-social-boxed td-social-font-icons" tdc_css="eyJhbGwiOnsibWFyZ2luLWJvdHRvbSI6IjM4IiwiZGlzcGxheSI6IiJ9LCJwb3J0cmFpdCI6eyJtYXJnaW4tYm90dG9tIjoiMzAiLCJkaXNwbGF5IjoiIn0sInBvcnRyYWl0X21heF93aWR0aCI6MTAxOCwicG9ydHJhaXRfbWluX3dpZHRoIjo3Njh9" custom_title="Stay Connected" block_template_id="td_block_template_8" f_header_font_family="712" f_header_font_transform="uppercase" f_header_font_weight="500" f_header_font_size="17" border_color="#dd3333"]
- Advertisement -spot_img

Latest Articles