Five things you should have in mind when using ChatGPT to generate code (with examples)
1. Understand the limitations – Code snippets may not be optimal or correct – they are based on patterns of existing code.
Example here.
2. Provide clear and specific prompts – The more specific and accurate you are – the better the output.
Question 1: Can you tell me why my Android application is crashing with a Permission Exception?
Answer: Android applications can crash with a Permission Exception when the app tries to perform an operation that requires a specific permission that is not granted by
the user. This exception is thrown when the app tries to access a protected resource or perform a protected operation without having the necessary permission.
Here are some common scenarios where a Permission Exception can occur:
- The app is trying to access the device’s camera or microphone, but the user has not granted the necessary permissions for the app to access these
resources. - The app is trying to read or write to a file or directory that is not accessible without the READ_EXTERNAL_STORAGE or WRITE_EXTERNAL_STORAGE
permissions. - The app is trying to access the device’s location without the ACCESS_FINE_LOCATION or 1ACCESS_COARSE_LOCATION1 permissions.
- The app is trying to access the internet without the INTERNET permission.
To fix this issue, you need to make sure that your app is requesting the necessary permissions from the user before accessing the protected resource or
performing the protected operation. Here are the steps you can follow: - Identify the specific permission that is causing the Permission Exception by checking the error message or stack trace in the logcat output.
- Make sure that the permission is declared in your app’s AndroidManifest.xml file. If the permission is not declared, add it to the manifest file.
- Request the necessary permissions from the user at runtime using the requestPermissions() method. This method should be called from an
activity or fragment that requires the permission. - Handle the result of the permission request in the onRequestPermissionsResult() method of the activity or fragment. Check if the user has granted
the permission and proceed with the protected operation if the permission is granted. If the permission is not granted, notify the user and handle the
situation accordingly.
Here is an example of how to request the READ_EXTERNAL_STORAGE permission at runtime:
private static final int REQUEST_READ_EXTERNAL_STORAGE = 1;
...
// Check if the app has permission to read from external storage
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
// If the permission is not granted, request it from the user
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
REQUEST_READ_EXTERNAL_STORAGE);
} else {
// If the permission is already granted, proceed with the protected operation
readFromExternalStorage();
}
...
// Handle the result of the permission request
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
int[] grantResults) {
if (requestCode == REQUEST_READ_EXTERNAL_STORAGE) {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// If the user grants the permission, proceed with the protected operation
readFromExternalStorage();
} else {
// If the user denies the permission, notify the user and handle the situation accordingly
Toast.makeText(this, "Permission denied", Toast.LENGTH_SHORT).show();
}
}
}
In this example, we check if the app has the READ_EXTERNAL_STORAGE permission using the checkSelfPermission() method. If the permission is not
granted, we request it from the user using the requestPermissions() method, passing in the permission name and a request code. If the permission is
already granted, we proceed with the protected operation (readFromExternalStorage() in this case).
We handle the result of the permission request in the onRequestPermissionsResult() method, checking if the user has granted the permission. If the user
grants the permission, we proceed with the protected operation. If the user denies the permission, we notify the user with a Toast message.
Question 2: Can you tell me why my application is crashing with a SecurityException when I call the TelephonyManager’s
registerTelephonyCallback method?
Answer: The SecurityException occurs when your application tries to perform an operation that it does not have permission to do. In this case, the
SecurityException is being thrown because your application is trying to register a telephony callback using the registerTelephonyCallback() method
in the TelephonyManager class without having the necessary permission.
To use the registerTelephonyCallback() method, your application must have the READ_PHONE_STATE permission, which allows your app to access the
device’s telephony status and information. If this permission is not declared in your app’s manifest file, you will need to add it.
Here are the steps to fix the SecurityException:
- Open your app’s AndroidManifest.xml file and make sure that the READ_PHONE_STATE permission is declared.
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
2. Check that the TelephonyManager instance is not null before calling registerTelephonyCallback(). This is because the TelephonyManager
instance may be null if the device does not support telephony or if the permission is not granted.
TelephonyManager telephonyManager =
(TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
if (telephonyManager != null) {
telephonyManager.registerTelephonyCallback(myTelephonyCallback, new Handler());
}
- If your app does not have the READ_PHONE_STATE permission, you will need to request it from the user at runtime. You can use the
requestPermissions() method to request the permission. The user will be prompted to grant or deny the permission.
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(
this,
new String[] { Manifest.permission.READ_PHONE_STATE },
PERMISSIONS_REQUEST_READ_PHONE_STATE);
} else {
// Permission has already been granted, register telephony callback
TelephonyManager telephonyManager
= (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
if (telephonyManager != null) {
telephonyManager.registerTelephonyCallback(
myTelephonyCallback, new Handler());
}
}
4. Handle the result of the permission request in the onRequestPermissionsResult() method. Check if the user has granted the permission and proceed
with the protected operation if the permission is granted.
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == PERMISSIONS_REQUEST_READ_PHONE_STATE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission has been granted, register telephony callback
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
if (telephonyManager != null) {
telephonyManager.registerTelephonyCallback(myTelephonyCallback, new Handler());
}
} else {
// Permission has been denied, notify the user
Toast.makeText(this, "Permission denied", Toast.LENGTH_SHORT).show();
}
}
}
By following these steps, you should be able to fix the SecurityException and successfully register a telephony callback using the TelephonyManager class.
Notes
I first asked ChatGPT a very general question, to which it replied with a very general answer. This is not bad, but I was looking for something more specific. This
is why, the second time I asked the question, I tried to provide as much context as I could. The result is a more concrete answer to my question.
3. Review the generated code – Review, refine and optimize. Code is not always great, so you better check it.
Question 1: Write a function in Python that geneates a random password.
Answer:
import random
import string
def generate_password(length):
# define the characters to choose from
characters = string.ascii_letters + string.digits + string.punctuation
# generate a password with the specified length
password = ''.join(random.choice(characters) for i in range(length))
return password
Question 2: Write unit tests for this function.
Answer:
import unittest
import string
import random
from my_module import generate_password
class TestGeneratePassword(unittest.TestCase):
def test_password_length(self):
for i in range(10):
length = random.randint(6, 20)
password = generate_password(length)
self.assertEqual(len(password), length)
def test_password_characters(self):
for i in range(10):
length = random.randint(6, 20)
password = generate_password(length)
for char in password:
self.assertIn(char, string.ascii_letters + string.digits + string.punctuation)
if name == ‘main‘:
unittest.main()
Notes
As we can see, it did not generate unit tests for all cases. Negative numbers are ignored, as well as 0 length passwords.
4. Use generated code for prototyping or experimentation.
Question: Can you give me the code for a authentication provider in a React Native Application using Typescript?
Answer: Sure, here’s an example authentication provider implementation in a React Native application using TypeScript:
import React, { createContext, useContext, useState } from 'react';
type User = {
email: string;
password: string;
}
type AuthContextType = {
user: User | null;
login: (email: string, password: string) => void;
logout: () => void;
}
const AuthContext = createContext<AuthContextType>({
user: null,
login: () => {},
logout: () => {}
});
export const useAuth = () => useContext(AuthContext);
export const AuthProvider: React.FC = ({ children }) => {
const [user, setUser] = useState<User | null>(null);
const login = (email: string, password: string) => {
// Your authentication logic here, e.g. calling an API endpoint to authenticate the user
// If the authentication succeeds, set the user object with the returned data
const authenticatedUser: User = { email, password };
setUser(authenticatedUser);
};
const logout = () => {
setUser(null);
};
return (
<AuthContext.Provider value={{ user, login, logout }}>
{children}
</AuthContext.Provider>
);
};
In this example, we create an AuthContext with an initial value of user: null, login: () => {} and logout: () => {}. We also create a useAuth hook to use this context in our components.
The AuthProvider component contains the state of our authentication logic. We have a useState hook to keep track of the authenticated user, and login and logout functions to authenticate and log out the user respectively. You will need to add your own authentication logic inside the login function to authenticate the user, such as calling an API endpoint. To use this provider, simply wrap your top-level component with it, like so:
import { AuthProvider } from './AuthProvider';
const App = () => {
return (
<AuthProvider>
{/* Your app components here */}
</AuthProvider>
);
};
export default App;
Now, any child component of AuthProvider can access the authentication state and functions through the useAuth hook.
Notes
We have to add our application components and we also have to implement the communication with the backend. This can be done via ChatGPT again but we need to ask it explicitly.
5. Don’t rely solely on generated code – Use your own expertise, best practices, and coding standards to write high-quality, reliable, and maintainable code. You’re the expert at this!
Question: How to create a TODO application with React using Typescript, Functional Components and Styled Components (styled library)?
Answer: To create a TODO application with React using Typescript, Functional Components, and Styled Components library, you can follow the steps below:
- Set up a new React project using create-react-app and add TypeScript to it. You can use the following command to create a new project with TypeScript:
npx create-react-app my-app --template typescript
2. Install the styled-components library using the following command:
npm install styled-components
3. Create a new file called Todo.tsx in the src/components directory. This file will contain the code for the Todo component.
4. Import React and styled-components at the top of the Todo.tsx file:
import React from 'react';
import styled from 'styled-components';
5. Create a styled component for the todo list using the styled-components library:
const TodoList = styled.ul`
list-style: none;
padding: 0;
margin: 0;
`;
6. Create a functional component for the Todo and add the TodoList styled component:
const Todo = () => {
return (
<div>
<TodoList>
{/* Add list of todos here */}
</TodoList>
</div>
);
};
7. Create a state variable for the list of todos using the useState hook:
const [todos, setTodos] = React.useState<string[]>([]);
8. Create a function to handle adding a new todo to the list:
const addTodo = (todo: string) => {
setTodos([...todos, todo]);
};
9. Add a form to the Todo component to allow users to add new todos:
const Todo = () => {
const [todo, setTodo] = React.useState('');
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
addTodo(todo);
setTodo('');
};
return (
<div>
<form onSubmit={handleSubmit}>
<input
type="text"
value={todo}
onChange={(e) => setTodo(e.target.value)}
/>
<button type="submit">Add</button>
</form>
<TodoList>
{todos.map((todo) => (
<li key={todo}>{todo}</li>
))}
</TodoList>
</div>
);
};
10. Export the Todo component from the Todo.tsx file:
export default Todo;
11. Import the Todo component into the App.tsx file and render it:
import React from 'react';
import Todo from './components/Todo';
function App() {
return (
<div>
<Todo />
</div>
);
}
export default App;
That’s it! You should now have a basic TODO application with React using TypeScript, functional components, and styled-components library. You can continue
to build on this by adding more functionality and styling to your application.
Notes
As we can see, ChatGPT generate code for a TODO application. However, there are a lot of places where we have to intervene. We have to separate the code
into files at the very least. We also have to proff read the code to make sure it doesn’t have any mistakes.