
【ChatGPTとClaude】Flutterの簡単な計算機を作成させる。
趣旨
「12 Days of OpenAI」 の Day 3 を書くつもりだったのですが、まだ発表されていないようなので、暇つぶしにChatGPT/ClaudeにFlutterの簡単な計算機を作成させてみました🧮
OpenAIも日曜日は休みなのかな📅
Flutter3で簡単な計算機アプリを作成してください。
【プロンプト】
Flutter3で簡単な計算機アプリを作成してください。
ChatGPT

お、おう・・・ 😅

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

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

ただし、このように「 1 + 2 」のような過程の表示が無いので、再度指示をする
例えば 「 1 + 2」の場合はそれを画面上に表示させるようにしてください。
【プロンプト】
例えば 「 1 + 2」の場合はそれを画面上に表示させるようにしてください。
ChatGPT

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

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

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

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技術などに興味のある方は、是非ご覧になってください。