initial commit

pull/1047/head
GoutamVerma 4 months ago
parent 9e8dd00f10
commit 9588b4fb5c

@ -0,0 +1,171 @@
# Calculator App
A modern, responsive calculator web application built with HTML, CSS, and JavaScript. This calculator supports basic arithmetic operations, decimal calculations, and includes advanced features like sign changes and comprehensive error handling.
![Calculator App](https://img.shields.io/badge/Status-Complete-brightgreen)
![HTML5](https://img.shields.io/badge/HTML5-E34F26?style=flat&logo=html5&logoColor=white)
![CSS3](https://img.shields.io/badge/CSS3-1572B6?style=flat&logo=css3&logoColor=white)
![JavaScript](https://img.shields.io/badge/JavaScript-F7DF1E?style=flat&logo=javascript&logoColor=black)
## ✨ Features
### Core Features
- **Digital Display**: Shows current number entered or result of last operation
- **Number Input**: Enter numbers up to 8 digits long (0-9)
- **Basic Operations**: Addition (+), Subtraction (-), Multiplication (×), Division (÷)
- **Clear Functions**:
- **C**: Clear last number or operation
- **AC**: Clear all and reset to 0
- **Error Handling**: Shows "ERR" for invalid operations or results exceeding 8 digits
### Bonus Features
- **Decimal Support**: Floating point numbers up to 3 decimal places
- **Sign Change**: +/- button to toggle between positive and negative numbers
- **Keyboard Support**: Full keyboard input support
- **Responsive Design**: Works on desktop, tablet, and mobile devices
- **Visual Feedback**: Button hover effects and animations
## 🚀 Demo
Open `index.html` in your web browser to see the calculator in action!
## 📁 Project Structure
```
calculator-app/
├── index.html # Main HTML structure
├── styles.css # CSS styling and responsive design
├── script.js # JavaScript functionality and logic
└── README.md # Project documentation
```
## 🛠️ Installation & Setup
1. **Clone or Download**: Get the project files to your local machine
2. **Open**: Simply open `index.html` in any modern web browser
3. **That's it!** No additional dependencies or build steps required
### Alternative: Live Server (Recommended for Development)
If you have VS Code with Live Server extension:
1. Right-click on `index.html`
2. Select "Open with Live Server"
3. The calculator will open in your browser with auto-reload
## 🎮 Usage
### Mouse/Touch Controls
- Click number buttons (0-9) to enter numbers
- Click operation buttons (+, -, ×, ÷) to perform calculations
- Click = to calculate the result
- Click C to clear the last entry
- Click AC to clear everything
- Click +/- to change the sign of the current number
- Click . to add decimal point
### Keyboard Controls
| Key | Action |
|-----|--------|
| 0-9 | Enter numbers |
| + | Addition |
| - | Subtraction |
| * | Multiplication |
| / | Division |
| = or Enter | Calculate result |
| . | Decimal point |
| Escape | Clear all (AC) |
| Backspace | Clear last (C) |
## 🔧 Technical Details
### Constraints & Limitations
- **No `eval()` function**: All calculations are performed using proper arithmetic operations
- **8-digit limit**: Numbers exceeding 8 digits will show "ERR"
- **3 decimal places**: Decimal precision limited to 3 places
- **Error handling**: Division by zero and overflow conditions are handled gracefully
### Browser Compatibility
- ✅ Chrome 60+
- ✅ Firefox 55+
- ✅ Safari 12+
- ✅ Edge 79+
## 📱 Responsive Design
The calculator is fully responsive and adapts to different screen sizes:
- **Desktop**: Full-size calculator with hover effects
- **Tablet**: Medium-size layout optimized for touch
- **Mobile**: Compact layout with larger touch targets
## 🎨 Customization
### Changing Colors
Edit the CSS variables in `styles.css`:
```css
/* Main colors */
.calculator { background: #2c3e50; }
.btn-operator { background: #e74c3c; }
.btn-equals { background: #27ae60; }
.btn-clear { background: #f39c12; }
```
### Modifying Button Layout
The grid layout can be adjusted in the `.buttons` class:
```css
.buttons {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 15px;
}
```
## 🐛 Error Handling
The calculator handles several error conditions:
1. **Division by Zero**: Shows "ERR" and resets after 2 seconds
2. **Overflow**: Numbers exceeding 8 digits show "ERR"
3. **Invalid Operations**: Malformed calculations are caught and handled
4. **Display Formatting**: Long numbers are formatted with commas for readability
## 🤝 Contributing
Feel free to contribute to this project! Here are some ways you can help:
1. **Bug Reports**: Found a bug? Open an issue with details
2. **Feature Requests**: Have an idea? Suggest new features
3. **Code Improvements**: Submit pull requests with enhancements
4. **Documentation**: Help improve this README
### Development Setup
1. Fork the repository
2. Make your changes
3. Test thoroughly
4. Submit a pull request
## 📄 License
This project is open source and available under the [MIT License](LICENSE).
## 🙋‍♂️ Support
If you encounter any issues or have questions:
1. Check the existing issues in the repository
2. Create a new issue with detailed information
3. Include screenshots if applicable
## 🔮 Future Enhancements
Potential features for future versions:
- [ ] Scientific calculator functions (sin, cos, tan, etc.)
- [ ] Memory functions (M+, M-, MR, MC)
- [ ] History of calculations
- [ ] Themes and color customization
- [ ] Unit conversions
- [ ] Export/share results
---
**Made with ❤️ using HTML, CSS, and JavaScript**
*This calculator was built as part of the App Ideas collection, focusing on clean code, user experience, and responsive design.*

@ -0,0 +1,49 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Calculator App</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="calculator">
<div class="display">
<div class="display-screen">0</div>
</div>
<div class="buttons">
<!-- First Row -->
<button class="btn btn-clear" data-action="clear-all">AC</button>
<button class="btn btn-clear" data-action="clear">C</button>
<button class="btn btn-operator" data-action="sign">+/-</button>
<button class="btn btn-operator" data-action="divide">÷</button>
<!-- Second Row -->
<button class="btn btn-number" data-number="7">7</button>
<button class="btn btn-number" data-number="8">8</button>
<button class="btn btn-number" data-number="9">9</button>
<button class="btn btn-operator" data-action="multiply">×</button>
<!-- Third Row -->
<button class="btn btn-number" data-number="4">4</button>
<button class="btn btn-number" data-number="5">5</button>
<button class="btn btn-number" data-number="6">6</button>
<button class="btn btn-operator" data-action="subtract">-</button>
<!-- Fourth Row -->
<button class="btn btn-number" data-number="1">1</button>
<button class="btn btn-number" data-number="2">2</button>
<button class="btn btn-number" data-number="3">3</button>
<button class="btn btn-operator" data-action="add">+</button>
<!-- Fifth Row -->
<button class="btn btn-number btn-zero" data-number="0">0</button>
<button class="btn btn-number" data-action="decimal">.</button>
<button class="btn btn-equals" data-action="calculate">=</button>
</div>
</div>
<script src="script.js"></script>
</body>
</html>

@ -0,0 +1,276 @@
class Calculator {
constructor() {
this.display = document.querySelector('.display-screen');
this.buttons = document.querySelector('.buttons');
this.currentNumber = '0';
this.previousNumber = null;
this.operation = null;
this.waitingForOperand = false;
this.maxDigits = 8;
this.init();
}
init() {
this.buttons.addEventListener('click', this.handleButtonClick.bind(this));
this.updateDisplay();
}
handleButtonClick(event) {
const button = event.target;
if (!button.classList.contains('btn')) return;
if (button.hasAttribute('data-number')) {
this.inputNumber(button.getAttribute('data-number'));
} else if (button.hasAttribute('data-action')) {
const action = button.getAttribute('data-action');
this.handleAction(action);
}
}
inputNumber(number) {
if (this.waitingForOperand) {
this.currentNumber = number;
this.waitingForOperand = false;
} else {
// Check if we're at the digit limit
const currentLength = this.currentNumber.replace('.', '').length;
if (currentLength >= this.maxDigits) {
return;
}
this.currentNumber = this.currentNumber === '0' ? number : this.currentNumber + number;
}
this.updateDisplay();
}
handleAction(action) {
switch (action) {
case 'clear-all':
this.clearAll();
break;
case 'clear':
this.clear();
break;
case 'sign':
this.changeSign();
break;
case 'decimal':
this.inputDecimal();
break;
case 'add':
case 'subtract':
case 'multiply':
case 'divide':
this.performOperation(action);
break;
case 'calculate':
this.calculate();
break;
}
}
clearAll() {
this.currentNumber = '0';
this.previousNumber = null;
this.operation = null;
this.waitingForOperand = false;
this.updateDisplay();
}
clear() {
if (this.operation && this.waitingForOperand) {
// If last action was an operation, clear it and show previous number
this.operation = null;
this.waitingForOperand = false;
this.currentNumber = this.previousNumber || '0';
this.previousNumber = null;
} else {
// Clear current number
this.currentNumber = '0';
}
this.updateDisplay();
}
changeSign() {
if (this.currentNumber !== '0') {
this.currentNumber = this.currentNumber.charAt(0) === '-'
? this.currentNumber.slice(1)
: '-' + this.currentNumber;
this.updateDisplay();
}
}
inputDecimal() {
if (this.waitingForOperand) {
this.currentNumber = '0.';
this.waitingForOperand = false;
} else if (this.currentNumber.indexOf('.') === -1) {
this.currentNumber += '.';
}
this.updateDisplay();
}
performOperation(nextOperation) {
const inputValue = parseFloat(this.currentNumber);
if (this.previousNumber === null) {
this.previousNumber = inputValue;
} else if (this.operation) {
const currentValue = this.previousNumber || 0;
const newValue = this.performCalculation(this.operation, currentValue, inputValue);
if (this.isError(newValue)) {
this.showError();
return;
}
this.currentNumber = String(newValue);
this.previousNumber = newValue;
}
this.waitingForOperand = true;
this.operation = nextOperation;
this.updateDisplay();
}
calculate() {
const inputValue = parseFloat(this.currentNumber);
if (this.previousNumber !== null && this.operation) {
const newValue = this.performCalculation(this.operation, this.previousNumber, inputValue);
if (this.isError(newValue)) {
this.showError();
return;
}
this.currentNumber = String(newValue);
this.previousNumber = null;
this.operation = null;
this.waitingForOperand = true;
this.updateDisplay();
}
}
performCalculation(operation, firstOperand, secondOperand) {
switch (operation) {
case 'add':
return firstOperand + secondOperand;
case 'subtract':
return firstOperand - secondOperand;
case 'multiply':
return firstOperand * secondOperand;
case 'divide':
if (secondOperand === 0) {
return NaN;
}
return firstOperand / secondOperand;
default:
return secondOperand;
}
}
isError(value) {
if (isNaN(value) || !isFinite(value)) {
return true;
}
// Check if result exceeds 8 digits (excluding decimal point)
const stringValue = String(Math.abs(value));
const integerPart = stringValue.split('.')[0];
return integerPart.length > this.maxDigits;
}
showError() {
this.display.textContent = 'ERR';
this.display.classList.add('error');
setTimeout(() => {
this.display.classList.remove('error');
this.clearAll();
}, 2000);
}
formatNumber(number) {
const parts = number.split('.');
const integerPart = parts[0];
const decimalPart = parts[1];
// Format integer part with commas for readability
const formattedInteger = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
if (decimalPart !== undefined) {
// Limit decimal places to 3
const limitedDecimal = decimalPart.slice(0, 3);
return formattedInteger + '.' + limitedDecimal;
}
return formattedInteger;
}
updateDisplay() {
// Remove commas for internal calculations
const cleanNumber = this.currentNumber.replace(/,/g, '');
// Format for display
if (cleanNumber === '0' || cleanNumber === '' || cleanNumber === '-0') {
this.display.textContent = '0';
} else {
this.display.textContent = this.formatNumber(cleanNumber);
}
}
}
// Initialize calculator when DOM is loaded
document.addEventListener('DOMContentLoaded', () => {
new Calculator();
});
// Keyboard support
document.addEventListener('keydown', (event) => {
const key = event.key;
let button = null;
if (key >= '0' && key <= '9') {
button = document.querySelector(`[data-number="${key}"]`);
} else {
switch (key) {
case '+':
button = document.querySelector('[data-action="add"]');
break;
case '-':
button = document.querySelector('[data-action="subtract"]');
break;
case '*':
button = document.querySelector('[data-action="multiply"]');
break;
case '/':
event.preventDefault(); // Prevent browser search
button = document.querySelector('[data-action="divide"]');
break;
case '=':
case 'Enter':
button = document.querySelector('[data-action="calculate"]');
break;
case '.':
button = document.querySelector('[data-action="decimal"]');
break;
case 'Escape':
button = document.querySelector('[data-action="clear-all"]');
break;
case 'Backspace':
button = document.querySelector('[data-action="clear"]');
break;
}
}
if (button) {
button.click();
button.classList.add('btn-active');
setTimeout(() => button.classList.remove('btn-active'), 100);
}
});

@ -0,0 +1,157 @@
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Arial', sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
padding: 20px;
}
.calculator {
background: #2c3e50;
border-radius: 20px;
padding: 20px;
box-shadow: 0 20px 50px rgba(0, 0, 0, 0.3);
width: 100%;
max-width: 400px;
}
.display {
background: #1a252f;
border-radius: 15px;
padding: 20px;
margin-bottom: 20px;
box-shadow: inset 0 3px 10px rgba(0, 0, 0, 0.3);
}
.display-screen {
color: #ffffff;
font-size: 2.5rem;
font-weight: 300;
text-align: right;
min-height: 60px;
display: flex;
align-items: center;
justify-content: flex-end;
word-wrap: break-word;
overflow-wrap: break-word;
}
.buttons {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 15px;
}
.btn {
background: #34495e;
border: none;
border-radius: 15px;
color: #ffffff;
font-size: 1.2rem;
font-weight: 500;
padding: 20px;
cursor: pointer;
transition: all 0.2s ease;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
user-select: none;
}
.btn:hover {
transform: translateY(-2px);
box-shadow: 0 6px 15px rgba(0, 0, 0, 0.3);
}
.btn:active {
transform: translateY(0);
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
}
.btn-number {
background: #34495e;
}
.btn-number:hover {
background: #4a6274;
}
.btn-operator {
background: #e74c3c;
}
.btn-operator:hover {
background: #c0392b;
}
.btn-equals {
background: #27ae60;
grid-column: span 2;
}
.btn-equals:hover {
background: #229954;
}
.btn-clear {
background: #f39c12;
}
.btn-clear:hover {
background: #d68910;
}
.btn-zero {
grid-column: span 2;
}
/* Error state */
.error {
color: #e74c3c !important;
animation: shake 0.5s ease-in-out;
}
@keyframes shake {
0%, 100% { transform: translateX(0); }
25% { transform: translateX(-5px); }
75% { transform: translateX(5px); }
}
/* Responsive design */
@media (max-width: 480px) {
.calculator {
padding: 15px;
margin: 10px;
}
.display-screen {
font-size: 2rem;
min-height: 50px;
}
.btn {
padding: 15px;
font-size: 1.1rem;
}
.buttons {
gap: 10px;
}
}
@media (max-width: 360px) {
.display-screen {
font-size: 1.8rem;
}
.btn {
padding: 12px;
font-size: 1rem;
}
}
Loading…
Cancel
Save