見出し画像

【ChatGPTとClaude】Flutterの簡単な計算機を作成させる。


趣旨

「12 Days of OpenAI」 の Day 3 を書くつもりだったのですが、まだ発表されていないようなので、暇つぶしにChatGPT/ClaudeにFlutterの簡単な計算機を作成させてみました🧮

OpenAIも日曜日は休みなのかな📅

Flutter3で簡単な計算機アプリを作成してください。

プロンプト
Flutter3で簡単な計算機アプリを作成してください。

ChatGPT

お、おう・・・ 😅

1 + 2 = 3

まあ、入力欄の形式も考えようによってはありかも。
入力欄の数を増やせるようカスタマイズするのも良いかも💡

Claude

まあ、普通はこうだよね。

1 + 2 = 3

ただし、このように「 1 + 2 」のような過程の表示が無いので、再度指示をする

例えば 「 1 + 2」の場合はそれを画面上に表示させるようにしてください。

プロンプト
例えば 「 1 + 2」の場合はそれを画面上に表示させるようにしてください。

ChatGPT

1 + 2 = 3

いきなり、本気を出してくるChatGPT🤣

パッケージでパースしている。

Claude

1 + 2 = 3

こちらもいい感じですね〜

Claudeの方は、ロジックでパースしている。

ボタン

プロンプト
ボタン

これね、間違って「ボタン」とだけ打ってEnterキー押しちゃったんですよね

ChatGPT

ボタン部分のコードの解説をしてくる。

Claude

何とデザイン/レイアウトを改良し始める

カラフルになる🎨

生成されたコード

main.dartのみ載せます(pubspec.yamlなどは割愛)
Claudeの方はボタンのデザインもしてくれた分、コードは長め。

書き方としてはChatGPTの方が分かりやすいかな🛠

ChatGPT

import 'package:flutter/material.dart';
import 'package:math_expressions/math_expressions.dart';

void main() {
  runApp(const CalculatorApp());
}

class CalculatorApp extends StatelessWidget {
  const CalculatorApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Calculator',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const CalculatorScreen(),
    );
  }
}

class CalculatorScreen extends StatefulWidget {
  const CalculatorScreen({super.key});

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

class _CalculatorScreenState extends State<CalculatorScreen> {
  String _input = ''; // ユーザーが入力した計算式
  String _result = ''; // 計算結果

  /// ボタンが押されたときの処理
  void _onButtonPressed(String value) {
    setState(() {
      if (value == '=') {
        // 計算処理
        try {
          _result = _calculate(_input);
        } catch (e) {
          _result = 'Error';
        }
      } else if (value == 'C') {
        // 入力と結果をクリア
        _input = '';
        _result = '';
      } else {
        // 式を更新
        _input += value;
      }
    });
  }

  /// 計算ロジック
  String _calculate(String expression) {
    try {
      final parser = Parser();
      final exp = parser.parse(expression.replaceAll('x', '*'));
      final contextModel = ContextModel();
      final result = exp.evaluate(EvaluationType.REAL, contextModel);
      return result.toString();
    } catch (e) {
      return 'Error';
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Calculator'),
      ),
      body: Column(
        children: [
          Expanded(
            child: Container(
              padding: const EdgeInsets.all(16.0),
              alignment: Alignment.bottomRight,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.end,
                crossAxisAlignment: CrossAxisAlignment.end,
                children: [
                  Text(
                    _input,
                    style: const TextStyle(fontSize: 32, fontWeight: FontWeight.bold),
                  ),
                  const SizedBox(height: 16),
                  Text(
                    _result,
                    style: const TextStyle(fontSize: 24, color: Colors.grey),
                  ),
                ],
              ),
            ),
          ),
          Container(
            color: Colors.grey[200],
            child: Column(
              children: [
                _buildButtonRow(['7', '8', '9', '/']),
                _buildButtonRow(['4', '5', '6', 'x']),
                _buildButtonRow(['1', '2', '3', '-']),
                _buildButtonRow(['C', '0', '=', '+']),
              ],
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildButtonRow(List<String> buttons) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      children: buttons.map((button) {
        return ElevatedButton(
          onPressed: () => _onButtonPressed(button),
          style: ElevatedButton.styleFrom(
            padding: const EdgeInsets.symmetric(vertical: 20.0, horizontal: 40.0),
          ),
          child: Text(
            button,
            style: const TextStyle(fontSize: 20),
          ),
        );
      }).toList(),
    );
  }
}

Claude

import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';

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

class CalculatorApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '電卓',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: Calculator(),
    );
  }
}

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

class _CalculatorState extends State<Calculator> {
  String _output = '0';
  String _calculation = '';
  double _num1 = 0.0;
  double _num2 = 0.0;
  String _operation = '';
  bool _showResult = false;

  void _buttonPressed(String buttonText) {
    setState(() {
      if (buttonText == 'C') {
        _output = '0';
        _calculation = '';
        _num1 = 0.0;
        _num2 = 0.0;
        _operation = '';
        _showResult = false;
      } else if (['+', '-', 'x', '/'].contains(buttonText)) {
        _num1 = double.parse(_output);
        _operation = buttonText;
        _calculation = '$_num1 $_operation ';
        _output = '0';
        _showResult = false;
      } else if (buttonText == '=') {
        _num2 = double.parse(_output);
        _calculation += _output;
        
        switch (_operation) {
          case '+':
            _output = (_num1 + _num2).toString();
            break;
          case '-':
            _output = (_num1 - _num2).toString();
            break;
          case 'x':
            _output = (_num1 * _num2).toString();
            break;
          case '/':
            _output = (_num1 / _num2).toString();
            break;
        }
        
        _showResult = true;
        _num1 = 0.0;
        _num2 = 0.0;
        _operation = '';
      } else {
        if (_output == '0') {
          _output = buttonText;
        } else {
          _output += buttonText;
        }
        
        if (_showResult) {
          _output = buttonText;
          _calculation = '';
          _showResult = false;
        }
      }
    });
  }

  Widget _buildButton(String buttonText, {Color? color, Color? textColor}) {
    return Expanded(
      child: Container(
        margin: EdgeInsets.all(4),
        child: ElevatedButton(
          style: ElevatedButton.styleFrom(
            backgroundColor: color ?? Colors.grey[300],
            foregroundColor: textColor ?? Colors.black,
            padding: EdgeInsets.symmetric(vertical: 20),
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(15),
            ),
            elevation: 5,
          ),
          onPressed: () => _buttonPressed(buttonText),
          child: Text(
            buttonText,
            style: GoogleFonts.roboto(
              fontSize: 24,
              fontWeight: FontWeight.bold,
            ),
          ),
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(
        title: Text(
          '電卓',
          style: GoogleFonts.roboto(),
        ),
        backgroundColor: Colors.blue,
      ),
      body: Column(
        children: <Widget>[
          // 計算過程の表示
          Container(
            alignment: Alignment.centerRight,
            padding: EdgeInsets.symmetric(
              vertical: 12.0,
              horizontal: 12.0,
            ),
            child: Text(
              _calculation,
              style: GoogleFonts.roboto(
                fontSize: 24.0,
                color: Colors.grey,
              ),
            ),
          ),
          // 現在の数値または結果の表示
          Container(
            alignment: Alignment.centerRight,
            padding: EdgeInsets.symmetric(
              vertical: 24.0,
              horizontal: 12.0,
            ),
            child: Text(
              _output,
              style: GoogleFonts.roboto(
                fontSize: 48.0,
                fontWeight: FontWeight.bold,
              ),
            ),
          ),
          Expanded(
            child: Divider(color: Colors.grey[300]),
          ),
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: Column(
              children: [
                Row(
                  children: [
                    _buildButton('7'),
                    _buildButton('8'),
                    _buildButton('9'),
                    _buildButton('/', color: Colors.orange, textColor: Colors.white),
                  ],
                ),
                Row(
                  children: [
                    _buildButton('4'),
                    _buildButton('5'),
                    _buildButton('6'),
                    _buildButton('x', color: Colors.orange, textColor: Colors.white),
                  ],
                ),
                Row(
                  children: [
                    _buildButton('1'),
                    _buildButton('2'),
                    _buildButton('3'),
                    _buildButton('-', color: Colors.orange, textColor: Colors.white),
                  ],
                ),
                Row(
                  children: [
                    _buildButton('C', color: Colors.red, textColor: Colors.white),
                    _buildButton('0'),
                    _buildButton('=', color: Colors.green, textColor: Colors.white),
                    _buildButton('+', color: Colors.orange, textColor: Colors.white),
                  ],
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

著書

辛島信芳の著書
IT技術などに興味のある方は、是非ご覧になってください。


いいなと思ったら応援しよう!

この記事が参加している募集