计算器

19 篇文章 1 订阅

计算器

Java


import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Stack;
import javax.swing.*;
 
class MyException extends Exception{
	public MyException() {
		super();
	}
	public MyException(String message) {
		super(message);
	}
}
 
 class SwingConsole{
	public static void run(final JFrame f,final int width,final int height){
		SwingUtilities.invokeLater(new Runnable(){
			public void run(){
				f.setTitle(f.getClass().getSimpleName());
				f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				f.setSize(width,height);
				f.setVisible(true);
			}
		});
	}
}
 
public class MyCalculator extends JFrame{
	/*
	 * 
	 */
 
	private JTextField textField;				//输入文本框
	private String input;						//结果
	private String operator;					//操作符
		
	public MyCalculator() {
		input = "";
		operator = "";
		
		Container container = this.getContentPane();
		JPanel panel = new JPanel();
		textField = new JTextField(30);
		textField.setEditable(false);						//文本框禁止编辑
		textField.setHorizontalAlignment(JTextField.LEFT);
		//textField.setBounds(100, 100, 20, 20);			//在容器布局为空情况下生效
		textField.setPreferredSize(new Dimension(200,30));
		container.add(textField, BorderLayout.NORTH);
		
		String[] name= {"7","8","9","+","4","5","6","-","1","2","3","*","0","C","=","/"};
		
		panel.setLayout(new GridLayout(4,4,1,1));
		
		for(int i=0;i<name.length;i++) {
			JButton button = new JButton(name[i]);
			button.addActionListener(new MyActionListener());
			panel.add(button);
		}
		container.add(panel,BorderLayout.CENTER);
	}
	
	class MyActionListener implements ActionListener{			//内部类实现按钮响应
 
		@Override
		public void actionPerformed(ActionEvent e) {
			int cnt=0;
			String actionCommand = e.getActionCommand();			//获取按钮上的字符串
			if(actionCommand.equals("+") || actionCommand.equals("-") || actionCommand.equals("*")
					|| actionCommand.equals("/")) {
				input += " " + actionCommand + " ";
			}
			else if(actionCommand.equals("C")) {					//清除输入
				input = "";
			} 
			else if(actionCommand.equals("=")) {					//按下等号
				try {
					input+= "="+calculate(input);
				} catch (MyException e1) {
					if(e1.getMessage().equals("Infinity"))
						input+= "=" + e1.getMessage();
					else
						input = e1.getMessage();
				}
				textField.setText(input);
				input="";
				cnt = 1;
			}
			else
				input += actionCommand;							//按下数字
			
			if(cnt == 0)
				textField.setText(input);
		}
	}
	
	private String calculate(String input) throws MyException{				//计算函数
		String[] comput = input.split(" ");					
		Stack<Double> stack = new Stack<>();
		Double m = Double.parseDouble(comput[0]);
		stack.push(m);										//第一个操作数入栈
		
		for(int i = 1; i < comput.length; i++) {
			if(i%2==1) {				
				if(comput[i].equals("+"))
					stack.push(Double.parseDouble(comput[i+1]));
				if(comput[i].equals("-"))
					stack.push(-Double.parseDouble(comput[i+1]));
				if(comput[i].equals("*")) {					//将前一个数出栈做乘法再入栈
					Double d = stack.peek();				//取栈顶元素
					stack.pop();
					stack.push(d*Double.parseDouble(comput[i+1]));
				}
				if(comput[i].equals("/")) {					//将前一个数出栈做乘法再入栈
					 double help = Double.parseDouble(comput[i+1]);  
					 if(help == 0)
						 throw new MyException("Infinity");			//不会继续执行该函数
					 double d = stack.peek(); 
					 stack.pop(); 
					 stack.push(d/help);  
				}
			}
		}
		
		double d = 0d;
		
		while(!stack.isEmpty()) {			//求和
			d += stack.peek();
			stack.pop();
		}
		
		String result = String.valueOf(d);
		return result;
	}
 
	public static void main(String[] args) {
		SwingConsole.run(new MyCalculator(), 250, 300);
	}
}

Py

import re  # 处理字符串的模块,如查找特定字符,删除特定字符,字符串分割等
# Tkinter模块("Tk 接口")是Python的标准Tk GUI工具包的接口,位Python的内置模块,直接import tkinter即可使用。
import tkinter
import tkinter.messagebox  # 调用tkinter模块中的messagebox函数,这个是消息框,对话框的关键,会弹出一个小框


def buttonClik(btn):
    content = contentVar.get()  # 获取文本框中的内容
    # 如果已有内容是以小数点开头的,在前面加0
    if content.startswith('.'):
        content = '0' + content  # 字符串可以直接用+来增加字符
    # 根据不同的按钮作出不同的反应
    if btn in '0123456789':
        content += btn  # 0-9中哪个键按下了,就在content字符串中增添
    elif btn == '.':
        # re.split,支持正则及多个字符切割
        # 将content从+-*/这些字符的地方分割开来,[-1]表示获取最后一个字符
        lastPart = re.split(r'\+|-|\*|/', content)[-1]
        if '.'in lastPart:
            tkinter.messagebox.showerror('错误', '重复出现的小数点')  # 出现对话框,并提示信息
            return
        else:
            content += btn
    elif btn == 'C':
        content = ''  # 清除文本框
    elif btn == '=':
        try:
            # 对输入的表达式求值
            content = str(eval(content))  # 调用函数eval,用字符串计算出结果
        except:
            tkinter.messagebox.showerror('错误', '表达式有误')
            return
    elif btn in operators:
        if content.endswith(operators):  # 如果content中最后出现的+-*/
            tkinter.messagebox.showerror('错误', '不允许存在连续运算符')
            return
        content += btn
    elif btn == 'Sqrt':
        n = content.split('.')  # 从.处分割存入n,n是一个列表
        if all(map(lambda x: x.isdigit(), n)):  # 如果列表中所有的都是数字,就是为了检查表达式是不是正确的
            content = eval(content)**0.5
        else:
            tkinter.messagebox.showerror('错误', '表达式错误')
            return
    contentVar.set(content)  # 将结果显示到文本框中


root = tkinter.Tk()  # 生成主窗口,用root表示,后面就在root操作
# 设置窗口大小和位置
root.geometry('300x270+400+100')  # 指定主框体大小
# 不允许改变窗口大小
root.resizable(False, False)  # 框体大小可调性,分别表示x,y方向的可变性;
# 设置窗口标题
root.title('计算器')

# 文本框和按钮都是tkinter中的组件
# Entry           文本框(单行);
# Button          按钮;
# 放置用来显示信息的文本框,设置为只读
# tkinter.StringVar    能自动刷新的字符串变量,可用set和get方法进行传值和取值
contentVar = tkinter.StringVar(root, '')
# 括号里面,可见第一个都是root,即表示都是以root为主界面的,将文本框中的内容存在contentVar中
contentEntry = tkinter.Entry(root, textvariable=contentVar)
contentEntry['state'] = 'readonly'  # 文本框只能读,不能写
# 文本框在root主界面的xy坐标位置,以及文本框自生的宽和高
contentEntry.place(x=10, y=10, width=280, height=20)
# x:            组件左上角的x坐标;
# y:             组件右上角的y坐标;
# 放置清除按钮和等号按钮
# 在root主界面中放置按钮,按钮上显示C,红色,点击按钮后进入buttonClik回调函数做进一步的处理,注意传入了参数‘C’,这样就能分清是哪个按钮按下了
btnClear = tkinter.Button(root, text='C', bg='red',
                          command=lambda: buttonClik('C'))
# 下面的内容和上面的模式都是一样的
btnClear.place(x=40, y=40, width=80, height=20)
btnCompute = tkinter.Button(
    root, text='=', bg='yellow', command=lambda: buttonClik('='))
btnCompute.place(x=170, y=40, width=80, height=20)

# 放置10个数字、小数点和计算平方根的按钮
# 序列list是Python中最基本的数据结构。序列中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,依此类推。
digits = list('0123456789.') + ['Sqrt']
index = 0
# 用循环的方式将上面数字、小数点、平方根这12个按钮分成四行三列进行放置
for row in range(4):
    for col in range(3):
        d = digits[index]  # 按索引从list中取值,和c语言中的数组类似
        index += 1  # 索引号递增
        btnDigit = tkinter.Button(
            root, text=d, command=lambda x=d: buttonClik(x))  # 和上面的是类似的
        btnDigit.place(x=20 + col * 70, y=80 + row * 50, width=50,
                       height=20)  # 很显然,每次放一个按钮的位置是不一样的,但是它们之间的关系时确定的
# 放置运算符按钮
operators = ('+', '-', '*', '/', '**', '//')  # Python的元组与列表类似,不同之处在于元组的元素不能修改。
# 元组使用小括号,列表使用方括号。
# enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。
for index, operator in enumerate(operators):
    btnOperator = tkinter.Button(
        root, text=operator, bg='orange', command=lambda x=operator: buttonClik(x))  # 创建的过程和上面类似
    btnOperator.place(x=230, y=80 + index * 30, width=50, height=20)

root.mainloop()  # 进入消息循环(必需组件)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值