In the modern era of being able to learn new things using Google, YouTube, and ChatGPT, can anybody just walk into the programming and app development world from off the street? Even if the answer is yes, it is a road that requires some patience and perserverance.

So you want to write an app?

In a recent post, I talked about what it requires to get ChatGPT to write an app for you. I went through all the planning and preparation you have to do even before you ever go to ChatGPT. And then once you are there, I stressed just how detailed you need to be in order for the code ChatGPT generates to match your vision. In the end, I had ChatGPT generate some useful, functioning (mostly), readable code that did most of what I asked it to do, despite being very thorough with what I asked. I concluded that I could have been even more detailed with my request, possibly separating my requirements into a numbered list, and interacted with ChatGPT more. But there was another approach that I suggested, which was coming to ChatGPT as a lay internet user with very general requirements.

Three people I know, who know me as a software developer, each told me that they wanted to write an app with ChatGPT – each of them with no software development or programming experience. I think every single one of us went into the experience skeptical but hopeful. In the end, it didn’t turn out the way they had hoped.

This is what I am exploring in this post. Exactly what does it look like for someone to come right off the street and enter the programming and app development world?

A practical app idea

I have a decently sized record collection, and I enjoy listening to vinyl records. Not long ago, I finally organized my collection in a way that allowed me to actually find the records I wanted to listen to. Before, they were randomly stored, and it often took too long for me to find a specific record that I wanted to listen to. The process of organizing my record collection reminded me of records that I forgot that I had, and I thought, I really should remember that and listen to it sometime. One of the simplest things to do would have been to grab a notepad and write them down in alphabetical order, which is essentially how I organized my collection (alphabetical by artist). But a handwritten list would get cumbersome as I added records to my collection, and plus, I’d love to see each album cover.

The next thought I had was to use an app to organize my record collection. Listen, I understand the pure irony of that statement. Yes, I am saying to use an app, something digital and very 21st century, to manage a collection of vinyl records, something analog and very 20th century. And what makes it even better is that I have Spotify on my phone, and could listen to most of this stuff digitally with just a quick search and the tap of a button. But again, I like listening to vinyl records. Well don’t be so surprised by the idea. There are already a number of apps that do just this, the most popular one being Discogs. What I didn’t necessarily like about Discogs is that when I go to add records to my collection, and I search for them, I got a lot of different results per each album, and I have no idea how to tell similar releases apart. This isn’t necessarily a deal breaker, and many other make that work just fine, but as a follow up thought, I decided I could write my own app.

Coming in from off the streets

I decided to take my “lay internet user” approach and see what ChatGPT could generate for me if I asked it to write an app. Though I have an idea for what I would like the app to look like, I decided to give ChatGPT a very general and creative liberty prompt:

Will you write code for an app that helps me manage my vinyl record collection by allowing me to create a list of my records and then search and filter that list? I’d like to be able to add one album at a time by name, artist, year of release, and be able add a photo of that album. In this list, I would like to see a thumbnail photo of each album, along with the album name, artist, and year of release. I also would like to be able to remove albums from this list.

ChatGPT’s response:

Sure, I can provide you with a basic outline of the code for such an app. We’ll create a simple console-based application in Python to manage your vinyl record collection.

class VinylRecord:
    def __init__(self, name, artist, year, photo):
        self.name = name
        self.artist = artist
        self.year = year
        self.photo = photo

class VinylCollection:
    def __init__(self):
        self.records = []

    def add_record(self, record):
        self.records.append(record)

    def remove_record(self, name):
        for record in self.records:
            if record.name == name:
                self.records.remove(record)
                return True
        return False

    def search_by_name(self, name):
        return [record for record in self.records if record.name.lower() == name.lower()]

    def search_by_artist(self, artist):
        return [record for record in self.records if record.artist.lower() == artist.lower()]

    def search_by_year(self, year):
        return [record for record in self.records if record.year == year]

    def display_records(self):
        for record in self.records:
            print("Name:", record.name)
            print("Artist:", record.artist)
            print("Year:", record.year)
            print("Photo:", record.photo)
            print()

# Example usage:
collection = VinylCollection()

def main():
    while True:
        print("1. Add Record")
        print("2. Remove Record")
        print("3. Search by Name")
        print("4. Search by Artist")
        print("5. Search by Year")
        print("6. Display Collection")
        print("7. Quit")

        choice = input("Enter your choice: ")

        if choice == "1":
            name = input("Enter record name: ")
            artist = input("Enter artist name: ")
            year = input("Enter year of release: ")
            photo = input("Enter photo URL: ")
            record = VinylRecord(name, artist, year, photo)
            collection.add_record(record)
            print("Record added successfully!\n")
        elif choice == "2":
            name = input("Enter record name to remove: ")
            if collection.remove_record(name):
                print("Record removed successfully!\n")
            else:
                print("Record not found!\n")
        elif choice == "3":
            name = input("Enter record name to search: ")
            result = collection.search_by_name(name)
            if result:
                collection.display_records()
            else:
                print("Record not found!\n")
        elif choice == "4":
            artist = input("Enter artist name to search: ")
            result = collection.search_by_artist(artist)
            if result:
                collection.display_records()
            else:
                print("Record not found!\n")
        elif choice == "5":
            year = input("Enter year to search: ")
            result = collection.search_by_year(year)
            if result:
                collection.display_records()
            else:
                print("Record not found!\n")
        elif choice == "6":
            collection.display_records()
        elif choice == "7":
            print("Exiting...")
            break
        else:
            print("Invalid choice. Please try again.\n")

if __name__ == "__main__":
    main()

This code creates two classes: VinylRecord to represent individual vinyl records and VinylCollection to manage the collection of records. The VinylCollection class provides methods to add, remove, search, and display records.

You can run this code in your Python environment and interact with it through the console. It allows you to add records, remove records, and search for records by name, artist, or year. The collection is displayed with all the record details. You’ll need to expand this to incorporate photo functionality, possibly by saving the photo URLs or image paths and displaying them accordingly.

Let’s talk about this response

In the second sentence of its response, ChatGPT mentions both console-based and Python. Because I am pretending to not have programing experience, I am trying to be an actor and assume the role of a “lay internet user.” I imagine they would see these words console-based and Python and not necessarily know what they are talking about.

I didn’t go so far as to pretend that I didn’t know what console-based or Python meant, but what I can imagine is that if a non-programmer saw that response, their follow up question would be how do I run this code? Or something like that. Probably people who even have the desire to have ChatGPT generate them code also have the understanding that code must be run after it is written. And ChatGPT is very good at explaining things like this. I could only guess how surprised they would be – after following ChatGPT’s instructions to install Python on your computer and then run the app – that the only way to interact with this “app” is via text and typing on their keyboard. This because it is just a console-based app. I put “app” in quotes, but by any formal definition, this is absolutely and app – it’s just not the kind of app a lay internet user would be thinking of. That might even be their next question. ChatGPT, how do you make this app the kind that works on a phone? And they would get their first lesson in the different types of apps that are out there. For brevity in this post though, I did not include that back-and-forth.

Adding additional clarity

Assuming that I would wind up at the point where I ask ChatGPT to try again but with a mobile-app this time, I followed that message up with this prompt:

That is great. Can you write code for a version of the app that is for a mobile device?

ChatGPT now gives a lengthy response that is more in line with my original idea:

Certainly! For a mobile app version, we can use a cross-platform framework like Flutter to build the app. Below is a basic outline of how you can create the vinyl record collection management app using Flutter:

import 'package:flutter/material.dart';

void main() {
  runApp(VinylCollectionApp());
}

class VinylRecord {
  final String name;
  final String artist;
  final int year;
  final String photo;

  VinylRecord({required this.name, required this.artist, required this.year, required this.photo});
}

class VinylCollection {
  List<VinylRecord> records = [];

  void addRecord(VinylRecord record) {
    records.add(record);
  }

  void removeRecord(int index) {
    records.removeAt(index);
  }
}

class VinylCollectionApp extends StatelessWidget {
  final VinylCollection collection = VinylCollection();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Vinyl Collection',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: VinylCollectionScreen(collection: collection),
    );
  }
}

class VinylCollectionScreen extends StatelessWidget {
  final VinylCollection collection;

  VinylCollectionScreen({required this.collection});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Vinyl Collection'),
      ),
      body: ListView.builder(
        itemCount: collection.records.length,
        itemBuilder: (BuildContext context, int index) {
          return ListTile(
            leading: Image.network(collection.records[index].photo), // Display thumbnail photo
            title: Text(collection.records[index].name),
            subtitle: Text('${collection.records[index].artist} - ${collection.records[index].year}'),
            trailing: IconButton(
              icon: Icon(Icons.delete),
              onPressed: () {
                collection.removeRecord(index);
              },
            ),
          );
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          Navigator.push(
            context,
            MaterialPageRoute(builder: (context) => AddRecordScreen(collection: collection)),
          );
        },
        child: Icon(Icons.add),
      ),
    );
  }
}

class AddRecordScreen extends StatefulWidget {
  final VinylCollection collection;

  AddRecordScreen({required this.collection});

  @override
  _AddRecordScreenState createState() => _AddRecordScreenState();
}

class _AddRecordScreenState extends State<AddRecordScreen> {
  final TextEditingController nameController = TextEditingController();
  final TextEditingController artistController = TextEditingController();
  final TextEditingController yearController = TextEditingController();
  final TextEditingController photoController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Add Record'),
      ),
      body: Padding(
        padding: EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            TextField(
              controller: nameController,
              decoration: InputDecoration(labelText: 'Record Name'),
            ),
            TextField(
              controller: artistController,
              decoration: InputDecoration(labelText: 'Artist'),
            ),
            TextField(
              controller: yearController,
              decoration: InputDecoration(labelText: 'Year of Release'),
              keyboardType: TextInputType.number,
            ),
            TextField(
              controller: photoController,
              decoration: InputDecoration(labelText: 'Photo URL'),
            ),
            SizedBox(height: 16.0),
            ElevatedButton(
              onPressed: () {
                final name = nameController.text;
                final artist = artistController.text;
                final year = int.tryParse(yearController.text) ?? 0;
                final photo = photoController.text;

                if (name.isNotEmpty && artist.isNotEmpty && year > 0 && photo.isNotEmpty) {
                  final record = VinylRecord(name: name, artist: artist, year: year, photo: photo);
                  widget.collection.addRecord(record);
                  Navigator.pop(context);
                } else {
                  // Show error message or handle invalid input
                }
              },
              child: Text('Add Record'),
            ),
          ],
        ),
      ),
    );
  }

  @override
  void dispose() {
    nameController.dispose();
    artistController.dispose();
    yearController.dispose();
    photoController.dispose();
    super.dispose();
  }
}

This code creates a basic Flutter app with two screens:

  1. VinylCollectionScreen: Displays the list of vinyl records. Each record is displayed as a ListTile with the record name, artist, year, and a thumbnail photo. You can delete records by tapping the delete icon.
  2. AddRecordScreen: Allows users to add a new record to the collection. Users can input the record name, artist, year of release, and photo URL. Upon adding a record, the user is navigated back to the collection screen.

You can run this code in a Flutter development environment and test it on Android or iOS devices. You’ll need to add more features and UI improvements according to your preferences and requirements. Additionally, you may want to enhance error handling and validation for user input.

Woah! What is all that?

If the lay internet user would have been confused by ChatGPT’s first response, then I can only imagine how they would respond to this response. Based on its response, there is a lot that ChatGPT assumes the user is comfortable with. It brings up a cross-platform framework like Flutter in its very first full sentence. Hopefully the user could pick out that we are using something called Flutter here instead of Python like we were using in the last code snippet. At least, enough to be able to ask a follow up question like how do I run this code?

If the user was tenacious enough to embark on a journey to write their own code without any prior experience, an obstacle like never having heard of Flutter before is not going to stop them! Never! Even without ChatGPT, one could use Google to search for Flutter and wind up on their site, and see a bit about getting started:

Flutter website getting started page

Hmmm… Development Platform… I recognize one of these symbols, so I’ll go and click the one I am familiar with. Then it asks the next question:

Flutter website prompt to select the type of app I intend to work on

Hmmm… Well I don’t see iPhone/iOS, but I am trying to write a mobile app, so I guess I’ll just choose Android. After all, it is what’s “Recommended.”

When you go to the next page, you are met with all sorts of terms with which you may need to gain familiarity, such as System Requirements, prerequisites like Git and Android Studio, developing with an IDE, whatever an SDK is and how to install it, and using PowerShell.

Flutter website instructions to install and use Flutter

As a lay internet user, whether you use ChatGPT, Google or YouTube to explain all of these foundational programming principles to you, ideally you will wind up at the point where you have:

  • Ensured your system meets the minimum requirements to build apps on it
  • Downloaded and installed all of the prerequisite tools (in this case, Git for Windows and Android Studio)
  • Downloaded and installed your Integrated Development Environment (IDE), which is where the code is written and run (and debugged)
  • Used your IDE (or some other means if you prefer) to install the Flutter Software Development Kit (SDK) onto your computer
  • Determined how to run the code from your IDE

It is important to note that you will not get very far just using a text editor alone. That is to say that if you copy the code from ChatGPT over to a regular text editor (like Notepad for Windows or TextEdit for macOS) and hope to run it somehow, don’t expect anything to happen. This is specifically why IDEs are helpful.

Something else I want to note is that there are many options for choices of code and tools that you could use to write an app that will run on a mobile device like an iPhone or an Android phone. These include using React Native, Cordova, PhoneGap, or native Swift (for iOS) or Java (for Android). I will not go into detail about any of those in this post. Flutter is also a fantastic choice for mobile app development, and I can’t help but wonder if ChatGPT chose this technology specifically because I have actually been trying to learn Flutter and was using ChatGPT to help me learn it. Or perhaps it was just random or based on entirely different criteria. Regardless, I would agree that it is a good choice for this pursuit.

Getting the app running

Since I happen to already have been trying to learn Flutter, I already had all the required setup completed on my system. For my IDE, I was already very comfortable with VSCode (Visual Studio Code), which happened to be the first suggestion in the Flutter “Getting Started” guide, pictured above. When I take the code out of ChatGPT and put it into VSCode, I am able to run it, and after a brief wait where it is processing the code, an app shows up!

Basic app created in Flutter by ChatGPT based on requirements

At the onsite, there is not much here. At the same time, I didn’t give it much to go on. But let’s test it out. I asked ChatGPT to make an app that allowed me to add records, and I see a + button, so let’s tap it and see what happens.

App screen where you enter your record information

Up comes this screen, and it seems like it is fulfilling my criteria to be able to add records to a list. Let me enter one of the records that I have in my collection. Note that for the photo of the record, it is specifically requesting a photo URL, or a link to a photo on the internet. Though what I hoped to be able to do was to add a picture of a record that I could take with my phone, I can’t say that I was actually specific enough when I gave that requirement to ChatGPT. All I stated was I wanted to add information about the record, “and be able add a photo of that album.” This is another example of ChatGPT giving us different results than we may have expected when trying to have it write an app. Being very specific about requirements was something I went over in my last post about this.

Wait a second, where is my mobile device?

You may have caught on to the fact that so far, I have been on my laptop this whole time, including interacting with the app. Flutter is versatile enough to also build apps that work directly in Windows, which is what platform I am using. If I wanted to be able to test this app on an iPhone or an Android phone, there would be even more steps that I haven’t even gone through in this post. And I feel like I have already gone through so many steps! My point being, if the lay internet user wants to build an app with no prior app building experience, it is not impossible, but there is a long road and an unignorable learning curve. And we are not done yet!

How well did it do?

Let’s say I enter information for one of my records. Since I can’t use the app to take a picture of my actual record, I find a link to a picture of it from Wikipedia. Here is all of the information filled out:

App "add record" information page with information entered in

Now we press the Add Record button and…

App with still an empty list, as it failed to add

…nothing happens. Did we enter it wrong? Did we press the wrong button? Did I accidentally leave something out? I click the + button again, go to the add record page, re-enter all of the information, and ensure I definitely press the Add Record button. But again, nothing happens. This seems like … a bug.

Now I go back to ChatGPT to express my dismay (but also say something nice first):

I like what you have created, but when I add records, I don’t see them appear in any sort of list. I can click the + button to add an entry, and I can fill it out, but after I click the Add Record button, I return to the initial screen and it remains unchanged.

ChatGPT responds:

It seems like the issue might be related to how the state is managed in the Flutter app. Let’s fix it by updating the VinylCollectionScreen to use setState whenever the collection changes:

class VinylCollectionScreen extends StatefulWidget {
  final VinylCollection collection;

  VinylCollectionScreen({required this.collection});

  @override
  _VinylCollectionScreenState createState() => _VinylCollectionScreenState();
}

class _VinylCollectionScreenState extends State<VinylCollectionScreen> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Vinyl Collection'),
      ),
      body: ListView.builder(
        itemCount: widget.collection.records.length,
        itemBuilder: (BuildContext context, int index) {
          return ListTile(
            leading: Image.network(widget.collection.records[index].photo), // Display thumbnail photo
            title: Text(widget.collection.records[index].name),
            subtitle: Text('${widget.collection.records[index].artist} - ${widget.collection.records[index].year}'),
            trailing: IconButton(
              icon: Icon(Icons.delete),
              onPressed: () {
                setState(() {
                  widget.collection.removeRecord(index);
                });
              },
            ),
          );
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          Navigator.push(
            context,
            MaterialPageRoute(builder: (context) => AddRecordScreen(collection: widget.collection)),
          ).then((value) {
            setState(() {}); // Update the state when returning from the AddRecordScreen
          });
        },
        child: Icon(Icons.add),
      ),
    );
  }
}

By calling setState after adding or removing a record, we notify Flutter to rebuild the UI with the updated collection data. This ensures that when you add a record and return to the VinylCollectionScreen, the screen will reflect the changes.

Now what?

By this point, we are neck deep in code and editors and installing and running and debugging. Never mind that we are a lay internet user. That’s just what we were when we started. Now, we are a programmer! And we are going to figure out exactly what to do with this response!

What you may notice is that ChatGPT did not just give us the full code again. It only gave us a snippet to replace. So now it is on us to figure out how to take what it gave us, and properly apply it to the original code that ChatGPT gave us. Or another approach we could take would be to just say to ChatGPT, Can you just give me all of the code again but with the update this time? And it is likely that ChatGPT will do that for you.

With the corrected code, I run it again (I had to stop it and exit the app to make the update), click the + button to get to the add record page, enter information, click Add Record, and voila! It shows in my list:

App with a record successfully added to the list

Three things that we can observe:

  • It correctly displays my record, as I described it. The words I used were In this list, I would like to see a thumbnail photo of each album, along with the album name, artist, and year of release.
  • It includes a trash can icon, which fulfills the requirements that I also would like to be able to remove albums from this list.
  • It does not include a way to search the albums, which was an important requirement for me in this app, and part of the point of having this app in the first place. The words I used were by allowing me to create a list of my records and then search and filter that list? Maybe I wasn’t specific enough in saying search and filter that list. Because technically, I can search it just by scrolling through it, although there is absolutely no concept of filtering.

In comparison to my previous attempt to have ChatGPT write an app for me, ChatGPT does not seem to nail all of the requirements. But let’s keep going and keep seeing how well the app does. I click the + button again and enter information for a second record:

I click the Add Record button now, and don’t get exactly the result that I intended:

App screen with list of records, but one of the record thumbnail images does not show

Well wait, what went wrong? Did I enter the image URL wrong? Maybe that’s why the image is not showing. Let me go and click the + button again and re-enter all of the information, and double check that I didn’t get the image URL wrong. Except when I press the + button, nothing happens. In fact, nothing is happening at all when I press anything in the app. Huh!?

As a formerly-lay internet user now-turned programmer, you would see this and have to problem solve, most likely never having encountered an issue like this before. But you are tenacious! You got this far, after all. The natural thing to do next would be to ask ChatGPT, um, I added a record, and the image didn’t show, and now my app is not doing anything at all. What is wrong?

As a seasoned programmer, I already know the first place to check. My IDE. And when I do, sure enough, I see that the app is paused, because an Exception occurred.

Visual Studio Code editor with the app running within it showing that the app has paused because it encountered an error

If we look closer at the upper right corner of the editor, we will see a little message with the text, Invalid image data.

Visual Studio code editor indicating that the exception was because of invalid image data

What does that mean? Well let’s put it like this. If the “add record” page asks for an image URL, technically I could type in anything in that field. I could type in random words or even random letters. The Flutter app is going to try its hardest to look up what I typed, and fetch that image from the internet. If it is unsuccessful, it just dies. It doesn’t know what else to do. Mostly this is because I didn’t tell it what to do. And this is the part where being a lay internet user and not a programmer where drive you crazy. Yes, you have to specify all of that. You have to make sure that your app has error handling built in. You have to think of things like, is there a limit to how long the album name can be? What happens if the user enters something other than a number for the year? Is that allowed? If it is, then how would I sort by release year? For this image issue, the logical thing to do would have been to check to see if the image URL was a valid URL, and if not, showing some sort of popup message saying, Invalid image URL. Please try adding the record again with a valid image URL. Oh, and also not dying when it gets an error. But again, ChatGPT didn’t necessarily know we wanted it to do that, because we didn’t ask it to do that.

We can attempt to keep running the app after it paused, or we can kill the app and start over. If we decide to start the app over, look what happens:

App main list screen after it is started a second time, but with no records in the list

Where did all of our records go?? Every time we stop the app and restart it, the list of records goes away too. That’s not what we wanted! Again, we never specified to ChatGPT that it had to store this list of records even after the app closes. You mean we have to specify that too? Sadly, yes. And now you have a clue into the life of a programmer. ChatGPT is really doing what many ordinary seasoned programmers would do. It got an extremely brief list of requirements and then built an app solely based on those. I’ll admit, ChatGPT did a little bit of thinking outside of the box, but only a moderate amount. This is often what programmers will do too. The requirements for your app must be very detailed and explicit and leave little room for guessing, because any time you leave a chance for a programmer to guess what you mean, there is a chance they will guess wrong.

So am I a programmer yet?

If you were able to

  • start from programming knowledge scratch
  • give ChatGPT a very high-level prompt on an app you wanted it to write
  • determined how to bridge the gap between what you started off knowing and what ChatGPT assumed you needed to know
  • interact with enough along the way to learn how to install the necessary components to get your development environment set up
  • actually run the code

Then I tip my hat to you! But are you a programmer now? Well let’s just say that you are as much of a programmer now as you would be a mechanic after learning how to replace the alternator in your car from YouTube. You now have a few extra tricks up your sleeve, but there is so much more to being considered a programmer, including understanding the principles of software engineering as well as computer science (those are two different things).

But the biggest question that I want to answer in this post is, Is it possible for a “lay internet user” to come into the programming world from off the streets and build an app, with the help of ChatGPT? The short answer is, technically yes. And this post is what it looks like. You have to be tenacious, you have to be an outside-of-the-box thinker, and you have to be skilled enough at breaking a problem (or knowledge gap) down to the smallest pieces in order to figure out how to build back up from there. And all of that takes a great deal of patience, as does gaining proficiency at any skill. If you lack any of those personal ingredients, then you will certainly be in over your head. But now that you have a taste of the sort of problems you need to solve, and what some of the solutions looked like, don’t let a lack of knowledge or experience stop you from gaining additional knowledge and experience. Hit up ChatGPT and go write an app!

Tags:

No responses yet

Leave a Reply

Your email address will not be published. Required fields are marked *