Skip to content

Commit

Permalink
Integral calculator for numerical methods v1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
steventete committed Nov 29, 2024
0 parents commit a657758
Show file tree
Hide file tree
Showing 13,898 changed files with 2,150,194 additions and 0 deletions.
The diff you're trying to view is too large. We only load the first 3000 changed files.
Empty file added README.md
Empty file.
Binary file added calculate-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added integral-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
181 changes: 181 additions & 0 deletions integral_app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
import sys
import numpy as np
from PyQt5.QtWidgets import (
QApplication, QMainWindow, QVBoxLayout, QHBoxLayout,
QLabel, QLineEdit, QPushButton, QTableWidget, QTableWidgetItem, QWidget, QGroupBox, QTabWidget, QMessageBox
)
from PyQt5.QtGui import QFont, QColor, QIcon
from PyQt5.QtCore import QSize
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas


class IntegralApp(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Calculadora de integración definida para métodos numéricos")
self.setGeometry(200, 200, 900, 700)
self.setWindowIcon(QIcon('integral-icon.png'))
self.showMaximized()
self.initUI()

def initUI(self):
# Cargar fuente Poppins
QApplication.setFont(QFont("Poppins", 12))

# Layout para la izquierda (inputs y botón)
left_layout = QVBoxLayout()

# Grupo para inputs
inputs_group = QGroupBox("Parámetros de Entrada")
inputs_group.setStyleSheet("QGroupBox { font-weight: medium; font-size: 24px;}")
inputs_layout = QVBoxLayout()

# Función
self.func_input = QLineEdit("1/(1-0.8**2)*np.sqrt(1-0.8**2*(np.sin(x))**2)")
inputs_layout.addWidget(self.create_input("Función f(x):", self.func_input))

# Límite inferior
self.a_input = QLineEdit("0.0")
inputs_layout.addWidget(self.create_input("Límite inferior a:", self.a_input))

# Límite superior
self.b_input = QLineEdit("np.pi/2")
inputs_layout.addWidget(self.create_input("Límite superior b:", self.b_input))

# Número de rectángulos
self.n_input = QLineEdit("8")
inputs_layout.addWidget(self.create_input("Número de rectángulos n:", self.n_input))

inputs_group.setLayout(inputs_layout)

# Botón de calcular
self.calculate_button = QPushButton("Calcular Integral")
self.calculate_button.setFixedHeight(40)
self.calculate_button.setFont(QFont("Poppins", 14, QFont.Bold))
self.calculate_button.setIcon(QIcon('calculate-icon.png'))
self.calculate_button.setIconSize(QSize(18, 18))
self.calculate_button.setText(" Calcular")
self.calculate_button.setStyleSheet("border-radius: 5px; cursor: pointer; border: 1px solid #ccc; background-color: #f0f0f0;")
self.calculate_button.clicked.connect(self.start_calculation)

left_layout.addWidget(inputs_group)
left_layout.addWidget(self.calculate_button)

# Layout para la derecha (tabla y gráfica en tabs)
right_layout = QVBoxLayout()

# Tabs
self.tabs = QTabWidget()
self.tabs.setFont(QFont("Poppins", 12))

# Tab de tabla
self.table_tab = QWidget()
self.table_layout = QVBoxLayout(self.table_tab)
self.table = QTableWidget()
self.table.setColumnCount(3)
self.table.setHorizontalHeaderLabels(["Área Izquierda", "Área Derecha", "Área Central"])
self.table.setFont(QFont("Poppins", 12))
self.table.setStyleSheet("gridline-color: #dcdcdc;")
self.table_layout.addWidget(self.table)

# Tab de gráfica
self.graph_tab = QWidget()
self.graph_layout = QVBoxLayout(self.graph_tab)
self.canvas = FigureCanvas(plt.figure())
self.graph_layout.addWidget(self.canvas)

# Agregar ambas pestañas al TabWidget
self.tabs.addTab(self.table_tab, "Tabla de Resultados")
self.tabs.addTab(self.graph_tab, "Gráfica")

# Agregar tabs a la parte derecha
right_layout.addWidget(self.tabs)

# Layout principal
central_widget = QWidget()
central_layout = QHBoxLayout(central_widget)
central_layout.addLayout(left_layout, 1)
central_layout.addLayout(right_layout, 2)

self.setCentralWidget(central_widget)

def create_input(self, label_text, input_widget):
container = QWidget()
layout = QVBoxLayout(container)
label = QLabel(label_text)
label.setFont(QFont("Poppins", 12))
layout.addWidget(label)
input_widget.setFont(QFont("Poppins", 12))
input_widget.setStyleSheet("padding: 5px; border: 1px solid #ccc; border-radius: 5px;")
layout.addWidget(input_widget)
return container

def start_calculation(self):
try:
# Obtener parámetros
f = self.func_input.text()
a = eval(self.a_input.text())
b = eval(self.b_input.text())
n = int(self.n_input.text())

# Crear vector x y cálculos
x = np.linspace(a, b, n + 1)
x_centro = (x[1:] + x[:-1]) / 2
delta_x = (b - a) / n

# Evaluación de la función f(x)
y = eval(f)
y_centro = eval(f.replace('x', 'x_centro'))
area_izq = [delta_x * y[i] for i in range(n)] + [np.sum(delta_x * y[:-1])]
area_der = [delta_x * y[i + 1] for i in range(n)] + [np.sum(delta_x * y[1:])]
area_centro = [delta_x * y_centro[i] for i in range(n)] + [np.sum(delta_x * y_centro)]

# Mostrar resultados en la tabla
self.table.setRowCount(n + 1)
for i in range(n + 1):
self.table.setItem(i, 0, QTableWidgetItem(str(area_izq[i])))
self.table.setItem(i, 1, QTableWidgetItem(str(area_der[i])))
self.table.setItem(i, 2, QTableWidgetItem(str(area_centro[i])))

# Ajustar automáticamente el tamaño de las columnas
self.table.resizeColumnsToContents()

# Resaltar fila final (TOTAL)
for col in range(3):
self.table.item(n, col).setBackground(QColor("#ffb2b2"))
self.table.item(n, col).setFont(QFont("Poppins", 12, QFont.Bold))

# Mostrar gráfica
self.plot_graph(x_centro, y, y_centro)

except Exception as e:
error_dialog = QMessageBox()
error_dialog.setIcon(QMessageBox.Critical)
error_dialog.setWindowTitle("Error")
error_dialog.setWindowIcon(QIcon('integral-icon.png'))
error_dialog.setText("Por favor, revise los parámetros.")
error_dialog.setInformativeText(str(e))
error_dialog.setStandardButtons(QMessageBox.Ok)
error_dialog.exec_()

def plot_graph(self, x, y, y_centro):
fig = self.canvas.figure
fig.clf()
ax = fig.add_subplot(111)
ax.plot(x, y[:len(x)], label='f(x)', color='red')
ax.fill_between(x, y[:len(x)], color='red', alpha=0.3)
ax.grid(True)
ax.set_title('Gráfica de la función', fontsize=14)
ax.set_xlabel('x', fontsize=12)
ax.set_ylabel('f(x)', fontsize=12)
ax.legend()

self.canvas.draw()


if __name__ == "__main__":
app = QApplication(sys.argv)
window = IntegralApp()
window.show()
sys.exit(app.exec_())
133 changes: 133 additions & 0 deletions venv/Lib/site-packages/PIL/BdfFontFile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
#
# The Python Imaging Library
# $Id$
#
# bitmap distribution font (bdf) file parser
#
# history:
# 1996-05-16 fl created (as bdf2pil)
# 1997-08-25 fl converted to FontFile driver
# 2001-05-25 fl removed bogus __init__ call
# 2002-11-20 fl robustification (from Kevin Cazabon, Dmitry Vasiliev)
# 2003-04-22 fl more robustification (from Graham Dumpleton)
#
# Copyright (c) 1997-2003 by Secret Labs AB.
# Copyright (c) 1997-2003 by Fredrik Lundh.
#
# See the README file for information on usage and redistribution.
#

"""
Parse X Bitmap Distribution Format (BDF)
"""
from __future__ import annotations

from typing import BinaryIO

from . import FontFile, Image

bdf_slant = {
"R": "Roman",
"I": "Italic",
"O": "Oblique",
"RI": "Reverse Italic",
"RO": "Reverse Oblique",
"OT": "Other",
}

bdf_spacing = {"P": "Proportional", "M": "Monospaced", "C": "Cell"}


def bdf_char(
f: BinaryIO,
) -> (
tuple[
str,
int,
tuple[tuple[int, int], tuple[int, int, int, int], tuple[int, int, int, int]],
Image.Image,
]
| None
):
# skip to STARTCHAR
while True:
s = f.readline()
if not s:
return None
if s[:9] == b"STARTCHAR":
break
id = s[9:].strip().decode("ascii")

# load symbol properties
props = {}
while True:
s = f.readline()
if not s or s[:6] == b"BITMAP":
break
i = s.find(b" ")
props[s[:i].decode("ascii")] = s[i + 1 : -1].decode("ascii")

# load bitmap
bitmap = bytearray()
while True:
s = f.readline()
if not s or s[:7] == b"ENDCHAR":
break
bitmap += s[:-1]

# The word BBX
# followed by the width in x (BBw), height in y (BBh),
# and x and y displacement (BBxoff0, BByoff0)
# of the lower left corner from the origin of the character.
width, height, x_disp, y_disp = (int(p) for p in props["BBX"].split())

# The word DWIDTH
# followed by the width in x and y of the character in device pixels.
dwx, dwy = (int(p) for p in props["DWIDTH"].split())

bbox = (
(dwx, dwy),
(x_disp, -y_disp - height, width + x_disp, -y_disp),
(0, 0, width, height),
)

try:
im = Image.frombytes("1", (width, height), bitmap, "hex", "1")
except ValueError:
# deal with zero-width characters
im = Image.new("1", (width, height))

return id, int(props["ENCODING"]), bbox, im


class BdfFontFile(FontFile.FontFile):
"""Font file plugin for the X11 BDF format."""

def __init__(self, fp: BinaryIO) -> None:
super().__init__()

s = fp.readline()
if s[:13] != b"STARTFONT 2.1":
msg = "not a valid BDF file"
raise SyntaxError(msg)

props = {}
comments = []

while True:
s = fp.readline()
if not s or s[:13] == b"ENDPROPERTIES":
break
i = s.find(b" ")
props[s[:i].decode("ascii")] = s[i + 1 : -1].decode("ascii")
if s[:i] in [b"COMMENT", b"COPYRIGHT"]:
if s.find(b"LogicalFontDescription") < 0:
comments.append(s[i + 1 : -1].decode("ascii"))

while True:
c = bdf_char(fp)
if not c:
break
id, ch, (xy, dst, src), im = c
if 0 <= ch < len(self.glyph):
self.glyph[ch] = xy, dst, src, im
Loading

0 comments on commit a657758

Please sign in to comment.