Xin chào mọi người, trong bài viết này mình sẽ sử dụng ChatGPT để tạo ra 1 ứng dụng máy tính cơ bản.
 
Với hầu hết những bạn mình từng hỗ trợ trong quá trình làm ứng dụng, ứng dụng máy tính và 300 bài code thiếu nhi thường là giai đoạn thử thách đầu tiên trong hành trình lập trình của các bạn.
 
Ứng dụng máy tính cơ bản là cách để các bạn có tư duy về lập trình ứng dụng: phân chia bố cục, xử lý các phép tính…Và tất nhiên, nó hoàn toàn có thể mở rộng ra theo nhiều cách. Ứng dụng máy tính trên ios 18 là 1 ví dụ cụ thể.
 
Với những bạn đã có base lập trình, 300 bài code thiếu nhi và các ứng dụng cơ bản như máy tính sẽ không khó. Nhưng với những bạn trái ngành, trái nghề, chưa có base lập trình, viết được 1 ứng dụng máy tính sẽ mất rất nhiều thời gian, và rất có thể sẽ chán nản, từ bỏ giữa chừng.
 
Bài viết này mình muốn đưa ra 1 góc nhìn về sử dụng AI, cụ thể là coi ChatGPTnhư 1 người bạn đồng hành, giúp mình nâng cao hiệu quả công việc.
 
Mình cùng bắt tay vào thử nghiệm với ChatGPT nhé. Bài này mình sẽ sử dụng 100% ChatGPT để thử nghiệm xem liệu ChatGPT có thể giúp mình tạo ra 1 ứng dụng máy tính cơ bản được hay không. Let 's try it.


Về ChatGPT, mình sử dụng ChatGPT 4o mini tạo link
 

Promt đầu tiên mình sử dụng:

  • Prompt
  • Code
tôi muốn làm 1 ứng dụng máy tính với flutter
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Calculator',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Calculator(),
    );
  }
}

class Calculator extends StatefulWidget {
  @override
  _CalculatorState createState() => _CalculatorState();
}

class _CalculatorState extends State<Calculator> {
  String _expression = '';
  String _result = '';

  void _appendText(String text) {
    setState(() {
      _expression += text;
    });
  }

  void _clear() {
    setState(() {
      _expression = '';
      _result = '';
    });
  }

  void _calculate() {
    try {
      final parsedExpression = _expression.replaceAll('×', '*').replaceAll('÷', '/');
      final evalResult = _evaluate(parsedExpression);
      setState(() {
        _result = evalResult.toString();
      });
    } catch (e) {
      setState(() {
        _result = 'Error';
      });
    }
  }

  double _evaluate(String expression) {
    final parser = ExpressionParser();
    final evaluator = ExpressionEvaluator();
    final exp = parser.parse(expression);
    return evaluator.eval(exp, {});
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Calculator'),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.end,
        children: <Widget>[
          Padding(
            padding: const EdgeInsets.all(16.0),
            child: Align(
              alignment: Alignment.centerRight,
              child: Text(
                _expression,
                style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
              ),
            ),
          ),
          Padding(
            padding: const EdgeInsets.all(16.0),
            child: Align(
              alignment: Alignment.centerRight,
              child: Text(
                _result,
                style: TextStyle(fontSize: 48, fontWeight: FontWeight.bold),
              ),
            ),
          ),
          Expanded(
            child: GridView.builder(
              gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 4,
                crossAxisSpacing: 8,
                mainAxisSpacing: 8,
              ),
              itemCount: 16,
              itemBuilder: (context, index) {
                return _buildButton(index);
              },
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildButton(int index) {
    final buttons = [
      '7', '8', '9', '÷',
      '4', '5', '6', '×',
      '1', '2', '3', '-',
      '0', '.', '=', '+',
    ];

    final buttonText = buttons[index];
    return ElevatedButton(
      onPressed: () {
        if (buttonText == '=') {
          _calculate();
        } else if (buttonText == 'C') {
          _clear();
        } else {
          _appendText(buttonText);
        }
      },
      child: Text(buttonText, style: TextStyle(fontSize: 24)),
    );
  }
}

//
pubspec.yaml

dependencies:
  flutter:
    sdk: flutter
  expressions: ^0.2.5

 

Kết quả:

Code ChatGPT gen ra bị thiếu 1 dòng import:

try_1_result

 

Tiếp tục hỏi ChatGPT

  • Prompt
  • Code
i không tìm thấy ExpressionParser và ExpressionEvaluator
import 'package:flutter/material.dart';
import 'package:expressions/expressions.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Calculator',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Calculator(),
    );
  }
}

class Calculator extends StatefulWidget {
  @override
  _CalculatorState createState() => _CalculatorState();
}

class _CalculatorState extends State<Calculator> {
  String _expression = '';
  String _result = '';

  void _appendText(String text) {
    setState(() {
      _expression += text;
    });
  }

  void _clear() {
    setState(() {
      _expression = '';
      _result = '';
    });
  }

  void _calculate() {
    try {
      final expression = _expression.replaceAll('×', '*').replaceAll('÷', '/');
      final exp = Expression.parse(expression);
      final evaluator = const ExpressionEvaluator();
      final evalResult = evaluator.eval(exp, {});
      setState(() {
        _result = evalResult.toString();
      });
    } catch (e) {
      setState(() {
        _result = 'Error';
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Calculator'),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.end,
        children: <Widget>[
          Padding(
            padding: const EdgeInsets.all(16.0),
            child: Align(
              alignment: Alignment.centerRight,
              child: Text(
                _expression,
                style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
              ),
            ),
          ),
          Padding(
            padding: const EdgeInsets.all(16.0),
            child: Align(
              alignment: Alignment.centerRight,
              child: Text(
                _result,
                style: TextStyle(fontSize: 48, fontWeight: FontWeight.bold),
              ),
            ),
          ),
          Expanded(
            child: GridView.builder(
              gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 4,
                crossAxisSpacing: 8,
                mainAxisSpacing: 8,
              ),
              itemCount: 16,
              itemBuilder: (context, index) {
                return _buildButton(index);
              },
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildButton(int index) {
    final buttons = [
      '7', '8', '9', '÷',
      '4', '5', '6', '×',
      '1', '2', '3', '-',
      '0', '.', '=', '+',
    ];

    final buttonText = buttons[index];
    return ElevatedButton(
      onPressed: () {
        if (buttonText == '=') {
          _calculate();
        } else if (buttonText == 'C') {
          _clear();
        } else {
          _appendText(buttonText);
        }
      },
      child: Text(buttonText, style: TextStyle(fontSize: 24)),
    );
  }
}

 

Kết quả:

Lần này ChatGPT đã khắc phục được lỗi trên, nhưng các button trông khá ngộ nghĩnh

try_2nd

 

Giảm kích thước button:

  • Prompt
  • Code
Giảm kích thước của các nút bấm xuống cho vừa trong 1 màn hình
import 'package:flutter/material.dart';
import 'package:expressions/expressions.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Calculator',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Calculator(),
    );
  }
}

class Calculator extends StatefulWidget {
  @override
  _CalculatorState createState() => _CalculatorState();
}

class _CalculatorState extends State<Calculator> {
  String _expression = '';
  String _result = '';

  void _appendText(String text) {
    setState(() {
      _expression += text;
    });
  }

  void _clear() {
    setState(() {
      _expression = '';
      _result = '';
    });
  }

  void _calculate() {
    try {
      final expression = _expression.replaceAll('×', '*').replaceAll('÷', '/');
      final exp = Expression.parse(expression);
      final evaluator = const ExpressionEvaluator();
      final evalResult = evaluator.eval(exp, {});
      setState(() {
        _result = evalResult.toString();
      });
    } catch (e) {
      setState(() {
        _result = 'Error';
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Calculator'),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.end,
        children: <Widget>[
          Padding(
            padding: const EdgeInsets.all(16.0),
            child: Align(
              alignment: Alignment.centerRight,
              child: Text(
                _expression,
                style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
              ),
            ),
          ),
          Padding(
            padding: const EdgeInsets.all(16.0),
            child: Align(
              alignment: Alignment.centerRight,
              child: Text(
                _result,
                style: TextStyle(fontSize: 48, fontWeight: FontWeight.bold),
              ),
            ),
          ),
          Expanded(
            child: GridView.builder(
              gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 4,
                crossAxisSpacing: 4, // Space between columns
                mainAxisSpacing: 4,  // Space between rows
              ),
              itemCount: 16,
              itemBuilder: (context, index) {
                return _buildButton(index);
              },
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildButton(int index) {
    final buttons = [
      '7', '8', '9', '÷',
      '4', '5', '6', '×',
      '1', '2', '3', '-',
      '0', '.', '=', '+',
    ];

    final buttonText = buttons[index];
    return Container(
      margin: EdgeInsets.all(4.0),
      child: ElevatedButton(
        style: ElevatedButton.styleFrom(
          primary: Colors.blue,
          onPrimary: Colors.white,
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(8),
          ),
          padding: EdgeInsets.all(16), // Adjust padding for button size
        ),
        child: Text(buttonText, style: TextStyle(fontSize: 20)),
        onPressed: () {
          if (buttonText == '=') {
            _calculate();
          } else if (buttonText == 'C') {
            _clear();
          } else {
            _appendText(buttonText);
          }
        },
      ),
    );
  }
}
  • Prompt
  • Code
nút bấm vẫn to, tôi muốn có ththấy toàn bộ nút bấm của số và biểu thức trong cùng 1 màn hình
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Calculator',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Calculator(),
    );
  }
}

class Calculator extends StatefulWidget {
  @override
  _CalculatorState createState() => _CalculatorState();
}

class _CalculatorState extends State<Calculator> {
  String _expression = '';
  String _result = '';

  void _appendText(String text) {
    setState(() {
      _expression += text;
    });
  }

  void _clear() {
    setState(() {
      _expression = '';
      _result = '';
    });
  }

  void _calculate() {
    try {
      final expression = _expression.replaceAll('×', '*').replaceAll('÷', '/');
      final evalResult = _evaluateExpression(expression);
      setState(() {
        _result = evalResult.toString();
      });
    } catch (e) {
      setState(() {
        _result = 'Error';
      });
    }
  }

  double _evaluateExpression(String expression) {
    try {
      final result = double.parse(expression);
      return result;
    } catch (e) {
      return 0.0;
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Calculator'),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.end,
        children: <Widget>[
          Padding(
            padding: const EdgeInsets.all(16.0),
            child: Align(
              alignment: Alignment.centerRight,
              child: Text(
                _expression,
                style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
              ),
            ),
          ),
          Padding(
            padding: const EdgeInsets.all(16.0),
            child: Align(
              alignment: Alignment.centerRight,
              child: Text(
                _result,
                style: TextStyle(fontSize: 36, fontWeight: FontWeight.bold),
              ),
            ),
          ),
          Expanded(
            child: GridView.builder(
              gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 4,
                crossAxisSpacing: 2, // Reduced spacing
                mainAxisSpacing: 2,  // Reduced spacing
              ),
              itemCount: 16,
              itemBuilder: (context, index) {
                return _buildButton(index);
              },
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildButton(int index) {
    final buttons = [
      '7', '8', '9', '÷',
      '4', '5', '6', '×',
      '1', '2', '3', '-',
      '0', '.', '=', '+',
    ];

    final buttonText = buttons[index];
    return Container(
      margin: EdgeInsets.all(2.0), // Smaller margin
      child: ElevatedButton(
        style: ElevatedButton.styleFrom(
          primary: Colors.blue,
          onPrimary: Colors.white,
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(8),
          ),
          padding: EdgeInsets.all(8), // Reduced padding
        ),
        child: Text(buttonText, style: TextStyle(fontSize: 18)), // Smaller font size
        onPressed: () {
          if (buttonText == '=') {
            _calculate();
          } else if (buttonText == 'C') {
            _clear();
          } else {
            _appendText(buttonText);
          }
        },
      ),
    );
  }
}

  • Prompt
  • Code
hiện tại16 nút bấm, tôi muốn 16 nút bấm này tỷ lệ theo màn hình, ví dụ kích thước tối đa của 1 nút bấm bằng 1/4 kích thước màn hình, để có thể hiển th16 nút bấm và ô nhập trong cùng 1 màn hình
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Calculator',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Calculator(),
    );
  }
}

class Calculator extends StatefulWidget {
  @override
  _CalculatorState createState() => _CalculatorState();
}

class _CalculatorState extends State<Calculator> {
  String _expression = '';
  String _result = '';

  void _appendText(String text) {
    setState(() {
      _expression += text;
    });
  }

  void _clear() {
    setState(() {
      _expression = '';
      _result = '';
    });
  }

  void _calculate() {
    try {
      final expression = _expression.replaceAll('×', '*').replaceAll('÷', '/');
      final evalResult = _evaluateExpression(expression);
      setState(() {
        _result = evalResult.toString();
      });
    } catch (e) {
      setState(() {
        _result = 'Error';
      });
    }
  }

  double _evaluateExpression(String expression) {
    try {
      final result = double.parse(expression);
      return result;
    } catch (e) {
      return 0.0;
    }
  }

  @override
  Widget build(BuildContext context) {
    final screenSize = MediaQuery.of(context).size;
    final buttonSize = (screenSize.width - 24) / 4; // Calculate button size

    return Scaffold(
      appBar: AppBar(
        title: Text('Calculator'),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.end,
        children: <Widget>[
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: Align(
              alignment: Alignment.centerRight,
              child: Container(
                width: screenSize.width - 24,
                child: Text(
                  _expression,
                  style: TextStyle(fontSize: buttonSize * 0.25, fontWeight: FontWeight.bold),
                  overflow: TextOverflow.ellipsis,
                  textAlign: TextAlign.right,
                ),
              ),
            ),
          ),
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: Align(
              alignment: Alignment.centerRight,
              child: Container(
                width: screenSize.width - 24,
                child: Text(
                  _result,
                  style: TextStyle(fontSize: buttonSize * 0.5, fontWeight: FontWeight.bold),
                  overflow: TextOverflow.ellipsis,
                  textAlign: TextAlign.right,
                ),
              ),
            ),
          ),
          Expanded(
            child: GridView.builder(
              gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 4,
                crossAxisSpacing: 8, // Space between buttons
                mainAxisSpacing: 8,  // Space between buttons
              ),
              itemCount: 16,
              itemBuilder: (context, index) {
                return _buildButton(index, buttonSize);
              },
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildButton(int index, double buttonSize) {
    final buttons = [
      '7', '8', '9', '÷',
      '4', '5', '6', '×',
      '1', '2', '3', '-',
      '0', '.', '=', '+',
    ];

    final buttonText = buttons[index];
    return Container(
      width: buttonSize,
      height: buttonSize,
      child: ElevatedButton(
        style: ElevatedButton.styleFrom(
          primary: Colors.blue,
          onPrimary: Colors.white,
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(8),
          ),
          padding: EdgeInsets.all(0), // Remove extra padding
        ),
        child: Text(
          buttonText,
          style: TextStyle(fontSize: buttonSize * 0.3), // Adjust font size
        ),
        onPressed: () {
          if (buttonText == '=') {
            _calculate();
          } else if (buttonText == 'C') {
            _clear();
          } else {
            _appendText(buttonText);
          }
        },
      ),
    );
  }
}

 

Kết quả sau vài lần thử:

Cuối cùng nhìn giao diện cũng đã cải thiện được đôi chút

try_3rd

 

Thêm nút C

  • Prompt
  • Code
thêm nút C, khi bấm sẽ xóa toàn bộ kết quả trước đó
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Calculator',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Calculator(),
    );
  }
}

class Calculator extends StatefulWidget {
  @override
  _CalculatorState createState() => _CalculatorState();
}

class _CalculatorState extends State<Calculator> {
  String _expression = '';
  String _result = '';

  void _appendText(String text) {
    setState(() {
      _expression += text;
    });
  }

  void _clear() {
    setState(() {
      _expression = '';
      _result = '';
    });
  }

  void _calculate() {
    try {
      final expression = _expression.replaceAll('×', '*').replaceAll('÷', '/');
      final evalResult = _evaluateExpression(expression);
      setState(() {
        _result = evalResult.toString();
      });
    } catch (e) {
      setState(() {
        _result = 'Error';
      });
    }
  }

  double _evaluateExpression(String expression) {
    try {
      final result = double.parse(expression);
      return result;
    } catch (e) {
      return 0.0;
    }
  }

  @override
  Widget build(BuildContext context) {
    final screenSize = MediaQuery.of(context).size;
    final buttonSize = (screenSize.width - 24) / 4; // Calculate button size

    return Scaffold(
      appBar: AppBar(
        title: Text('Calculator'),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.end,
        children: <Widget>[
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: Align(
              alignment: Alignment.centerRight,
              child: Container(
                width: screenSize.width - 24,
                child: Text(
                  _expression,
                  style: TextStyle(fontSize: buttonSize * 0.25, fontWeight: FontWeight.bold),
                  overflow: TextOverflow.ellipsis,
                  textAlign: TextAlign.right,
                ),
              ),
            ),
          ),
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: Align(
              alignment: Alignment.centerRight,
              child: Container(
                width: screenSize.width - 24,
                child: Text(
                  _result,
                  style: TextStyle(fontSize: buttonSize * 0.5, fontWeight: FontWeight.bold),
                  overflow: TextOverflow.ellipsis,
                  textAlign: TextAlign.right,
                ),
              ),
            ),
          ),
          Expanded(
            child: GridView.builder(
              gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 4,
                crossAxisSpacing: 8, // Space between buttons
                mainAxisSpacing: 8,  // Space between buttons
              ),
              itemCount: 17, // 16 buttons + 1 for 'C'
              itemBuilder: (context, index) {
                return _buildButton(index, buttonSize);
              },
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildButton(int index, double buttonSize) {
    final buttons = [
      'C', '7', '8', '9', '÷',
      '4', '5', '6', '×',
      '1', '2', '3', '-',
      '0', '.', '=', '+',
    ];

    final buttonText = buttons[index];
    return Container(
      width: buttonSize,
      height: buttonSize,
      child: ElevatedButton(
        style: ElevatedButton.styleFrom(
          primary: Colors.blue,
          onPrimary: Colors.white,
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(8),
          ),
          padding: EdgeInsets.all(0), // Remove extra padding
        ),
        child: Text(
          buttonText,
          style: TextStyle(fontSize: buttonSize * 0.3), // Adjust font size
        ),
        onPressed: () {
          if (buttonText == '=') {
            _calculate();
          } else if (buttonText == 'C') {
            _clear();
          } else {
            _appendText(buttonText);
          }
        },
      ),
    );
  }
}

 

Thêm formatter:

  • Prompt
  • Code
tôi muốn kết quả hiển thị có ngăn cách phần nghìn. Ví dụ 1000 sẽ hiển thị 1,000
dependencies:
  flutter:
    sdk: flutter
  intl: ^0.18.0

import 'package:flutter/material.dart';
import 'package:intl/intl.dart'; // Import intl

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Calculator',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Calculator(),
    );
  }
}

class Calculator extends StatefulWidget {
  @override
  _CalculatorState createState() => _CalculatorState();
}

class _CalculatorState extends State<Calculator> {
  String _expression = '';
  String _result = '';

  void _appendText(String text) {
    setState(() {
      _expression += text;
    });
  }

  void _clear() {
    setState(() {
      _expression = '';
      _result = '';
    });
  }

  void _calculate() {
    try {
      final expression = _expression.replaceAll('×', '*').replaceAll('÷', '/');
      final evalResult = _evaluateExpression(expression);
      setState(() {
        _result = _formatNumber(evalResult); // Format result with thousand separators
      });
    } catch (e) {
      setState(() {
        _result = 'Error';
      });
    }
  }

  double _evaluateExpression(String expression) {
    try {
      final result = double.parse(expression);
      return result;
    } catch (e) {
      return 0.0;
    }
  }

  String _formatNumber(double number) {
    final formatter = NumberFormat('#,###.##'); // Format with thousand separators
    return formatter.format(number);
  }

  @override
  Widget build(BuildContext context) {
    final screenSize = MediaQuery.of(context).size;
    final buttonSize = (screenSize.width - 24) / 4; // Calculate button size

    return Scaffold(
      appBar: AppBar(
        title: Text('Calculator'),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.end,
        children: <Widget>[
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: Align(
              alignment: Alignment.centerRight,
              child: Container(
                width: screenSize.width - 24,
                child: Text(
                  _expression,
                  style: TextStyle(fontSize: buttonSize * 0.25, fontWeight: FontWeight.bold),
                  overflow: TextOverflow.ellipsis,
                  textAlign: TextAlign.right,
                ),
              ),
            ),
          ),
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: Align(
              alignment: Alignment.centerRight,
              child: Container(
                width: screenSize.width - 24,
                child: Text(
                  _result,
                  style: TextStyle(fontSize: buttonSize * 0.5, fontWeight: FontWeight.bold),
                  overflow: TextOverflow.ellipsis,
                  textAlign: TextAlign.right,
                ),
              ),
            ),
          ),
          Expanded(
            child: GridView.builder(
              gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 4,
                crossAxisSpacing: 8, // Space between buttons
                mainAxisSpacing: 8,  // Space between buttons
              ),
              itemCount: 17, // 16 buttons + 1 for 'C'
              itemBuilder: (context, index) {
                return _buildButton(index, buttonSize);
              },
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildButton(int index, double buttonSize) {
    final buttons = [
      'C', '7', '8', '9', '÷',
      '4', '5', '6', '×',
      '1', '2', '3', '-',
      '0', '.', '=', '+',
    ];

    final buttonText = buttons[index];
    return Container(
      width: buttonSize,
      height: buttonSize,
      child: ElevatedButton(
        style: ElevatedButton.styleFrom(
          primary: Colors.blue,
          onPrimary: Colors.white,
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(8),
          ),
          padding: EdgeInsets.all(0), // Remove extra padding
        ),
        child: Text(
          buttonText,
          style: TextStyle(fontSize: buttonSize * 0.3), // Adjust font size
        ),
        onPressed: () {
          if (buttonText == '=') {
            _calculate();
          } else if (buttonText == 'C') {
            _clear();
          } else {
            _appendText(buttonText);
          }
        },
      ),
    );
  }
}

 

Kết quả

Mình thử và không thấy nó hoạt động đúng như mình mong muốn. Thường khi sử dụng ChatGPT và các công cụ AI khác, điều này mình thường gặp khá nhiều.

Thường cách xử lý của mình sẽ là đưa ra vấn đề hiện tại, mong muốn của mình, và yêu cầu ChatGPT khắc phụ nó.

Trong cùng 1 đoạn hội thoại, ChatGPT đã nắm rõ context của mình, tức mình đang có 1 ứng dụng máy tính, có các phép tính cơ bản, và hiện tại tính năng thêm phần ngăn cách hàng nghìn đang không hoạt động.

  • Prompt
  • Code
tôi không thấy nó hoạt động
import 'package:flutter/material.dart';
import 'package:intl/intl.dart'; // Import intl

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Calculator',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Calculator(),
    );
  }
}

class Calculator extends StatefulWidget {
  @override
  _CalculatorState createState() => _CalculatorState();
}

class _CalculatorState extends State<Calculator> {
  String _expression = '';
  String _result = '';

  void _appendText(String text) {
    setState(() {
      _expression += text;
    });
  }

  void _clear() {
    setState(() {
      _expression = '';
      _result = '';
    });
  }

  void _calculate() {
    try {
      final expression = _expression.replaceAll('×', '*').replaceAll('÷', '/');
      final evalResult = _evaluateExpression(expression);
      setState(() {
        _result = _formatNumber(evalResult); // Format result with thousand separators
      });
    } catch (e) {
      setState(() {
        _result = 'Error';
      });
    }
  }

  double _evaluateExpression(String expression) {
    try {
      final result = double.parse(expression);
      return result;
    } catch (e) {
      return 0.0;
    }
  }

  String _formatNumber(double number) {
    final formatter = NumberFormat('#,###.##'); // Format with thousand separators
    return formatter.format(number);
  }

  @override
  Widget build(BuildContext context) {
    final screenSize = MediaQuery.of(context).size;
    final buttonSize = (screenSize.width - 24) / 4; // Calculate button size

    return Scaffold(
      appBar: AppBar(
        title: Text('Calculator'),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.end,
        children: <Widget>[
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: Align(
              alignment: Alignment.centerRight,
              child: Container(
                width: screenSize.width - 24,
                child: Text(
                  _expression,
                  style: TextStyle(fontSize: buttonSize * 0.25, fontWeight: FontWeight.bold),
                  overflow: TextOverflow.ellipsis,
                  textAlign: TextAlign.right,
                ),
              ),
            ),
          ),
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: Align(
              alignment: Alignment.centerRight,
              child: Container(
                width: screenSize.width - 24,
                child: Text(
                  _result,
                  style: TextStyle(fontSize: buttonSize * 0.5, fontWeight: FontWeight.bold),
                  overflow: TextOverflow.ellipsis,
                  textAlign: TextAlign.right,
                ),
              ),
            ),
          ),
          Expanded(
            child: GridView.builder(
              gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 4,
                crossAxisSpacing: 8, // Space between buttons
                mainAxisSpacing: 8,  // Space between buttons
              ),
              itemCount: 17, // 16 buttons + 1 for 'C'
              itemBuilder: (context, index) {
                return _buildButton(index, buttonSize);
              },
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildButton(int index, double buttonSize) {
    final buttons = [
      'C', '7', '8', '9', '÷',
      '4', '5', '6', '×',
      '1', '2', '3', '-',
      '0', '.', '=', '+',
    ];

    final buttonText = buttons[index];
    return Container(
      width: buttonSize,
      height: buttonSize,
      child: ElevatedButton(
        style: ElevatedButton.styleFrom(
          primary: Colors.blue,
          onPrimary: Colors.white,
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(8),
          ),
          padding: EdgeInsets.all(0), // Remove extra padding
        ),
        child: Text(
          buttonText,
          style: TextStyle(fontSize: buttonSize * 0.3), // Adjust font size
        ),
        onPressed: () {
          if (buttonText == '=') {
            _calculate();
          } else if (buttonText == 'C') {
            _clear();
          } else {
            _appendText(buttonText);
          }
        },
      ),
    );
  }
}
  • Prompt
  • Code
tôi thử 123 + 456, kết quả là 0
import 'package:flutter/material.dart';
import 'package:intl/intl.dart'; // Import intl
import 'package:expressions/expressions.dart'; // Import expressions

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Calculator',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Calculator(),
    );
  }
}

class Calculator extends StatefulWidget {
  @override
  _CalculatorState createState() => _CalculatorState();
}

class _CalculatorState extends State<Calculator> {
  String _expression = '';
  String _result = '';

  void _appendText(String text) {
    setState(() {
      _expression += text;
    });
  }

  void _clear() {
    setState(() {
      _expression = '';
      _result = '';
    });
  }

  void _calculate() {
    try {
      // Replace characters for correct evaluation
      final expression = _expression
          .replaceAll('×', '*')
          .replaceAll('÷', '/');
      
      // Evaluate the expression
      final evalResult = _evaluateExpression(expression);
      
      setState(() {
        _result = _formatNumber(evalResult); // Format result with thousand separators
      });
    } catch (e) {
      setState(() {
        _result = 'Error';
      });
    }
  }

  double _evaluateExpression(String expression) {
    try {
      final expr = Expression.parse(expression);
      final evaluator = const ExpressionEvaluator();
      final result = evaluator.eval(expr, {});
      return result.toDouble();
    } catch (e) {
      return 0.0;
    }
  }

  String _formatNumber(double number) {
    final formatter = NumberFormat('#,###.##'); // Format with thousand separators
    return formatter.format(number);
  }

  @override
  Widget build(BuildContext context) {
    final screenSize = MediaQuery.of(context).size;
    final buttonSize = (screenSize.width - 24) / 4; // Calculate button size

    return Scaffold(
      appBar: AppBar(
        title: Text('Calculator'),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.end,
        children: <Widget>[
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: Align(
              alignment: Alignment.centerRight,
              child: Container(
                width: screenSize.width - 24,
                child: Text(
                  _expression,
                  style: TextStyle(fontSize: buttonSize * 0.25, fontWeight: FontWeight.bold),
                  overflow: TextOverflow.ellipsis,
                  textAlign: TextAlign.right,
                ),
              ),
            ),
          ),
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: Align(
              alignment: Alignment.centerRight,
              child: Container(
                width: screenSize.width - 24,
                child: Text(
                  _result,
                  style: TextStyle(fontSize: buttonSize * 0.5, fontWeight: FontWeight.bold),
                  overflow: TextOverflow.ellipsis,
                  textAlign: TextAlign.right,
                ),
              ),
            ),
          ),
          Expanded(
            child: GridView.builder(
              gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 4,
                crossAxisSpacing: 8, // Space between buttons
                mainAxisSpacing: 8,  // Space between buttons
              ),
              itemCount: 17, // 16 buttons + 1 for 'C'
              itemBuilder: (context, index) {
                return _buildButton(index, buttonSize);
              },
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildButton(int index, double buttonSize) {
    final buttons = [
      'C', '7', '8', '9', '÷',
      '4', '5', '6', '×',
      '1', '2', '3', '-',
      '0', '.', '=', '+',
    ];

    final buttonText = buttons[index];
    return Container(
      width: buttonSize,
      height: buttonSize,
      child: ElevatedButton(
        style: ElevatedButton.styleFrom(
          primary: Colors.blue,
          onPrimary: Colors.white,
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(8),
          ),
          padding: EdgeInsets.all(0), // Remove extra padding
        ),
        child: Text(
          buttonText,
          style: TextStyle(fontSize: buttonSize * 0.3), // Adjust font size
        ),
        onPressed: () {
          if (buttonText == '=') {
            _calculate();
          } else if (buttonText == 'C') {
            _clear();
          } else {
            _appendText(buttonText);
          }
        },
      ),
    );
  }
}

Sau 2 lần giải thích, kết quả đã như mình mong muốn:
try_4th

 

Thêm ngăn cách phần nghìn ở cả ô nhập:

Phần này mình có thử 1 vài promt, nhưng chưa hoạt động đúng ở các case mình mong muốn. Coi như 1 challenge nhỏ cho người đọc :D

  • Prompt 1
  • Prompt 2
  • Prompt 3
  • Prompt 4
  • Prompt 4
tôi muốn thêm cả phần ngăn cách phần nghìn ở ô nhập. Ví dụ người dùng nhập 1000 + 2000 sẽ hiển thị là 1,000 + 2,000. Khi người dùng bấm = sẽ cho ra kết quả là 3,000
khi tôi nhập 789, kết quả của ô nhập là 7777,77877,777,789
khi tôi nhập 1234 kết quả hiển thị đúng như tôi mong đợi1,234 Nhưng tôi không thbấm dấu + để thực hiện phép tính
i đã thử đoạn code trên, khi bấm dấu + chỉ có số trong ô nhập, tôi không ththực hiện phép tính
i vẫn không thể nhập các phép tính

 

Kết quả:

Sau khi chạy toàn bộ promt trên, mình quyết định debug và tự xử nó.


Kết quả cuối cùng

try_final

Vậy là chỉ với vài prompt, thêm 1 chút thời gian debug, mình đã có 1 ứng dụng máy tính cơ bản.

 
Có 1 vài điểm mình muốn nhấn mạnh khi dùng các AI nói chung và ChatGPT nói riêng:

  • Hãy đặt mình là 1 đứa trẻ, tò mò mọi thứ xung quanh. Khi không biết về điều gì đó, hãy mạnh dạn đặt câu hỏi.
  • AI cũng như 1 người bạn đồng hành, muốn AI đưa ra câu hỏi chính xác, câu hỏi cần phải đủ thông tin, và đi đúng vào vấn đề. Nếu câu trả lời nhận về chưa đúng với mong muốn của bạn. Hãy thử thay đổi tư duy, góc nhìn và đưa ra câu hỏi mới. Nên áp dụng tư duy ngược mỗi khi nhận được câu trả lời chưa đúng.
  • Đừng quá lạm dụng ChatGPT và AI:
    • Chỉ với 1 vài promt, mình đã có 1 ứng dụng máy tính cơ bản. Nếu mình hiểu về các phần code AI gen ra, và có thể sửa nó, mọi thứ đều ổn. Nhưng nếu bạn không biết cách để sửa code, chắc chắn bạn sẽ phụ thuộc nhiều vào AI. Và tất nhiên, lúc đó giới hạn của AI chính là giới hạn của bạn.
    • Biết, vận dụng được AI là tốt, nhưng khi đi làm, nhà tuyển dụng sẽ yêu cầu bạn cần có nhiều kiến thức chứ không phải chỉ biết prompt.

Ngoài ra, mọi người có thể thử nghiệm, mở rộng ứng dụng máy tính ra theo nhiều cách như:

  • Bổ sung các phép tính năng cao: sin, cos, log, sqrt…
  • Thêm các phần lịch sử

 

Để nâng cao trình độ chuyên môn, thử 10000 lần với 1 bài toán không có gì là lạ, điển hình như tạo ra 1 form đăng nhập theo nhiều cách khác nhau, viết và tổ chức code theo các cách thức khác nhau.

Hy vọng với ví dụ trên, mọi người có thêm góc nhìn và hiểu hơn về người bạn AI. Mình luôn tin AI sẽ càng ngày càng thông minh hơn, và giúp ích được nhiều hơn nữa ở các bài toán phức tạp.