hashirlodhi's picture
Update app.py
3242017 verified
import gradio as gr
import plotly.graph_objects as go
import plotly.express as px
from plotly.subplots import make_subplots
import numpy as np
from collections import Counter
import math
# Historical researchers of perfect numbers - Enhanced HTML version
MATHEMATICIANS = """
<div style='background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 25px; border-radius: 15px; box-shadow: 0 8px 16px rgba(0,0,0,0.2); color: white; font-family: Arial, sans-serif;'>
<h2 style='text-align: center; margin-top: 0; font-size: 24px; text-shadow: 2px 2px 4px rgba(0,0,0,0.3);'>๐ŸŽ“ Notable Mathematicians & Their Contributions</h2>
<div style='background: rgba(255,255,255,0.15); padding: 15px; border-radius: 10px; margin: 15px 0; border-left: 5px solid #ffd700;'>
<strong style='font-size: 16px; color: #ffd700;'>โญ Euclid</strong> <em style='color: #e0e0e0;'>(c. 300 BCE)</em><br/>
<span style='margin-left: 20px; line-height: 1.6;'>Proved that 2<sup>(p-1)</sup> ร— (2<sup>p</sup> - 1) generates perfect numbers when 2<sup>p</sup> - 1 is prime</span>
</div>
<div style='background: rgba(255,255,255,0.15); padding: 15px; border-radius: 10px; margin: 15px 0; border-left: 5px solid #ff6b6b;'>
<strong style='font-size: 16px; color: #ff6b6b;'>โญ Leonhard Euler</strong> <em style='color: #e0e0e0;'>(1707-1783)</em><br/>
<span style='margin-left: 20px; line-height: 1.6;'>Proved all even perfect numbers follow Euclid's formula</span>
</div>
<div style='background: rgba(255,255,255,0.15); padding: 15px; border-radius: 10px; margin: 15px 0; border-left: 5px solid #4ecdc4;'>
<strong style='font-size: 16px; color: #4ecdc4;'>โญ Marin Mersenne</strong> <em style='color: #e0e0e0;'>(1588-1648)</em><br/>
<span style='margin-left: 20px; line-height: 1.6;'>Studied primes of form 2<sup>p</sup> - 1 (Mersenne primes), linked to perfect numbers</span>
</div>
<div style='background: rgba(255,255,255,0.15); padding: 15px; border-radius: 10px; margin: 15px 0; border-left: 5px solid #95e1d3;'>
<strong style='font-size: 16px; color: #95e1d3;'>โญ Niccolรฒ Paganini</strong><br/>
<span style='margin-left: 20px; line-height: 1.6;'>Not the violinist! Ancient Greek mathematician who studied perfect numbers</span>
</div>
<div style='background: rgba(255,255,255,0.15); padding: 15px; border-radius: 10px; margin: 15px 0; border-left: 5px solid #f38181;'>
<strong style='font-size: 16px; color: #f38181;'>โญ Renรฉ Descartes</strong> <em style='color: #e0e0e0;'>(1596-1650)</em><br/>
<span style='margin-left: 20px; line-height: 1.6;'>Conjectured properties about odd perfect numbers</span>
</div>
<div style='background: rgba(255,255,255,0.15); padding: 15px; border-radius: 10px; margin: 15px 0; border-left: 5px solid #aa96da;'>
<strong style='font-size: 16px; color: #aa96da;'>โญ Pierre de Fermat</strong> <em style='color: #e0e0e0;'>(1607-1665)</em><br/>
<span style='margin-left: 20px; line-height: 1.6;'>Contributed to number theory including perfect number properties</span>
</div>
<div style='background: rgba(255,255,255,0.15); padding: 15px; border-radius: 10px; margin: 15px 0; border-left: 5px solid #fcbad3;'>
<strong style='font-size: 16px; color: #fcbad3;'>โญ Pythagoras</strong> <em style='color: #e0e0e0;'>(c. 570-495 BCE)</em><br/>
<span style='margin-left: 20px; line-height: 1.6;'>Ancient Greek philosopher who ascribed mystical properties to perfect numbers</span>
</div>
<div style='background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); padding: 20px; border-radius: 10px; margin-top: 25px; text-align: center; box-shadow: 0 4px 8px rgba(0,0,0,0.2);'>
<h3 style='margin: 0 0 10px 0; font-size: 20px; color: white; text-shadow: 2px 2px 4px rgba(0,0,0,0.3);'>๐Ÿ“Š Known Perfect Numbers</h3>
<p style='margin: 10px 0; font-size: 16px; line-height: 1.6;'>Only <strong style='font-size: 22px; color: #ffd700;'>51</strong> perfect numbers have been discovered (as of 2024)</p>
<p style='margin: 10px 0; font-size: 14px;'>The first few:</p>
<p style='font-size: 18px; font-weight: bold; color: #ffd700; text-shadow: 1px 1px 2px rgba(0,0,0,0.3);'>6, 28, 496, 8128, 33550336...</p>
</div>
</div>
"""
def prime_factorization(n):
"""Get prime factorization of n"""
factors = []
d = 2
temp = n
while d * d <= temp:
while temp % d == 0:
factors.append(d)
temp //= d
d += 1
if temp > 1:
factors.append(temp)
return factors
def divisors(n):
"""Find all divisors of n efficiently"""
if n == 1:
return [1]
divs = set()
sqrt_n = int(math.isqrt(n))
for i in range(1, sqrt_n + 1):
if n % i == 0:
divs.add(i)
divs.add(n // i)
return sorted(divs)
def classify_number(n, proper_sum):
"""Classify number as perfect, abundant, or deficient"""
if proper_sum == n:
return "Perfect", "โœ…"
elif proper_sum > n:
return "Abundant", "๐Ÿ“ˆ"
else:
return "Deficient", "๐Ÿ“‰"
def check_perfect(n):
"""Check if number is perfect and return detailed info"""
if n <= 1:
return False, [], 0, "Invalid", ""
divs = divisors(n)
proper_divs = [d for d in divs if d != n]
proper_sum = sum(proper_divs)
classification, emoji = classify_number(n, proper_sum)
return proper_sum == n, divs, proper_sum, classification, emoji
def create_enhanced_visualization(n):
"""Create comprehensive visualization with Plotly for any positive integer"""
try:
n = int(n)
except (ValueError, TypeError):
return "Please enter a valid positive integer.", None
if n <= 0:
return "Please enter a positive integer.", None
is_perfect, divs, proper_sum, classification, emoji = check_perfect(n)
proper_divs = [d for d in divs if d != n]
# Create subplots with Plotly
fig = make_subplots(
rows=2, cols=3,
subplot_titles=(
f'Proper Divisors of {n}',
'Divisor Magnitudes',
f'{classification} Number Analysis {emoji}',
'Divisor Pairs',
f'Prime Factorization of {n}',
'Perfect Number Definition'
),
specs=[
[{"type": "pie"}, {"type": "bar"}, {"type": "bar"}],
[{"type": "table"}, {"type": "table"}, {"type": "table"}]
],
vertical_spacing=0.1,
horizontal_spacing=0.05
)
# Define color scheme
if classification == "Perfect":
main_color = '#2ecc71'
colors = px.colors.sequential.Greens[2:8]
elif classification == "Abundant":
main_color = '#3498db'
colors = px.colors.sequential.Blues[2:8]
else:
main_color = '#e74c3c'
colors = px.colors.sequential.Reds[2:8]
# 1. PIE CHART - Divisor Distribution
if proper_divs:
# Limit to top 20 divisors for readability
display_divs = proper_divs[:20] if len(proper_divs) > 20 else proper_divs
fig.add_trace(
go.Pie(
labels=[str(d) for d in display_divs],
values=display_divs,
textinfo='label+percent',
insidetextorientation='radial',
marker=dict(colors=colors * (len(display_divs) // len(colors) + 1)),
textfont=dict(size=12),
hovertemplate="Divisor: %{label}<br>Value: %{value}<extra></extra>"
),
row=1, col=1
)
# 2. BAR CHART - Divisor Values
if proper_divs:
# Limit to top 20 divisors for readability
display_divs = proper_divs[:20] if len(proper_divs) > 20 else proper_divs
fig.add_trace(
go.Bar(
x=[str(d) for d in display_divs],
y=display_divs,
marker_color=main_color,
text=display_divs,
textposition='outside',
hovertemplate="Divisor: %{x}<br>Value: %{y}<extra></extra>"
),
row=1, col=2
)
fig.update_xaxes(tickangle=45, row=1, col=2)
# 3. COMPARISON BAR - Sum vs Number
comparison = [proper_sum, n]
labels = [f'Sum of Divisors<br>({proper_sum})', f'Number<br>({n})']
fig.add_trace(
go.Bar(
x=labels,
y=comparison,
marker_color=[main_color, '#95a5a6'],
text=comparison,
textposition='outside',
hovertemplate="%{x}<br>Value: %{y}<extra></extra>"
),
row=1, col=3
)
# Add difference annotation
diff = abs(proper_sum - n)
diff_pct = (diff / n) * 100 if n != 0 else 0
fig.add_annotation(
x=0.5, y=max(comparison) * 0.5,
text=f"Difference: {diff}<br>({diff_pct:.1f}%)",
showarrow=False,
bgcolor="wheat",
bordercolor="black",
font=dict(size=12, color="black"),
row=1, col=3
)
# 4. DIVISOR PAIRS VISUALIZATION
sqrt_n = int(math.isqrt(n))
pairs = []
for d in proper_divs:
if d <= sqrt_n and d != n // d:
pairs.append((d, n // d))
if pairs:
pair_labels = [f"{d1} ร— {d2}" for d1, d2 in pairs]
pair_values = [n] * len(pairs)
fig.add_trace(
go.Table(
header=dict(values=["Divisor Pairs", "Product"]),
cells=dict(values=[pair_labels, pair_values]),
columnwidth=[100, 50]
),
row=2, col=1
)
else:
fig.add_trace(
go.Table(
header=dict(values=["Divisor Pairs"]),
cells=dict(values=[["No pairs found"]])
),
row=2, col=1
)
# 5. PRIME FACTORIZATION
prime_factors = prime_factorization(n)
if prime_factors:
factor_counts = Counter(prime_factors)
factor_parts = []
for prime in sorted(factor_counts.keys()):
count = factor_counts[prime]
if count == 1:
factor_parts.append(f"{prime}")
else:
factor_parts.append(f"{prime}^{count}")
factorization = " ร— ".join(factor_parts)
else:
factorization = "1 (unity)"
properties = [
f"Total divisors: {len(divs)}",
f"Proper divisors: {len(proper_divs)}",
f"Sum of all divisors: {sum(divs)}",
f"Classification: {classification} {emoji}"
]
fig.add_trace(
go.Table(
header=dict(values=["Prime Factorization", "Number Properties"]),
cells=dict(values=[[factorization], ["<br>".join(properties)]])
),
row=2, col=2
)
# 6. MATHEMATICAL FORMULA
if proper_divs:
sum_parts = " + ".join([str(d) for d in proper_divs[:10]]) # Limit to first 10
if len(proper_divs) > 10:
sum_parts += " + ..."
formula = f"{sum_parts} = {proper_sum}"
else:
formula = "No proper divisors"
result = f"{'โœ…' if is_perfect else 'โŒ'} {proper_sum} {'=' if is_perfect else 'โ‰ '} {n}"
if is_perfect:
conclusion = "PERFECT NUMBER! ๐ŸŽ‰"
elif classification == "Abundant":
conclusion = f"Abundant (Excess: {proper_sum - n})"
else:
conclusion = f"Deficient (Deficiency: {n - proper_sum})"
fig.add_trace(
go.Table(
header=dict(values=["Perfect Number Definition"]),
cells=dict(values=[[formula, result, conclusion]])
),
row=2, col=3
)
# Update layout
fig.update_layout(
height=800,
showlegend=False,
title_text=f"Comprehensive Analysis of {n}",
title_x=0.5,
title_font_size=24,
plot_bgcolor='rgba(0,0,0,0)',
paper_bgcolor='rgba(0,0,0,0)'
)
# Generate detailed message with HTML formatting
msg = f"""
<div style='font-family: Arial, sans-serif; background: linear-gradient(to right, #e0f7fa, #e1bee7); padding: 25px; border-radius: 15px; box-shadow: 0 4px 12px rgba(0,0,0,0.15);'>
<div style='background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%); color: white; padding: 20px; border-radius: 10px; margin-bottom: 20px; text-align: center; box-shadow: 0 4px 8px rgba(0,0,0,0.2);'>
<h1 style='margin: 0; font-size: 28px; text-shadow: 2px 2px 4px rgba(0,0,0,0.3);'>๐Ÿ” ANALYSIS OF NUMBER: {n}</h1>
</div>
<div style='background: {"linear-gradient(135deg, #11998e 0%, #38ef7d 100%)" if is_perfect else "linear-gradient(135deg, #ee0979 0%, #ff6a00 100%)" if classification == "Abundant" else "linear-gradient(135deg, #fc4a1a 0%, #f7b733 100%)"}; padding: 20px; border-radius: 10px; margin-bottom: 20px; box-shadow: 0 4px 8px rgba(0,0,0,0.2);'>
<h2 style='color: white; margin-top: 0; font-size: 22px; text-shadow: 2px 2px 4px rgba(0,0,0,0.3);'>๐Ÿ“Œ Classification: {classification} Number {emoji}</h2>
</div>
<div style='background: white; padding: 20px; border-radius: 10px; margin-bottom: 20px; box-shadow: 0 2px 6px rgba(0,0,0,0.1); border-left: 6px solid #2196F3;'>
<h3 style='color: #1976D2; margin-top: 0;'>๐Ÿ“Š Divisor Information</h3>
<p style='font-size: 16px; line-height: 1.8; color: #000;'><strong style='color: #000;'>All Divisors:</strong> <span style='color: #0D47A1; font-weight: bold;'>{divs[:20]}{"..." if len(divs) > 20 else ""}</span></p>
<p style='font-size: 16px; line-height: 1.8; color: #000;'><strong style='color: #000;'>Proper Divisors (excluding {n}):</strong> <span style='color: #0D47A1; font-weight: bold;'>{proper_divs[:20]}{"..." if len(proper_divs) > 20 else ""}</span></p>
</div>
<div style='background: white; padding: 20px; border-radius: 10px; margin-bottom: 20px; box-shadow: 0 2px 6px rgba(0,0,0,0.1); border-left: 6px solid #FF9800;'>
<h3 style='color: #F57C00; margin-top: 0;'>๐Ÿงฎ Sum Calculation</h3>
<p style='font-size: 18px; line-height: 1.8; font-weight: bold;'>
{' + '.join([f"<span style='background: #FFE0B2; color: #BF360C; padding: 3px 8px; border-radius: 5px; margin: 2px; display: inline-block;'>{d}</span>" for d in proper_divs[:10]])}{" + ..." if len(proper_divs) > 10 else ""} = <span style='background: #FF6F00; color: white; padding: 5px 12px; border-radius: 5px;'>{proper_sum}</span>
</p>
</div>
<div style='background: {"linear-gradient(135deg, #00b09b 0%, #96c93d 100%)" if is_perfect else "linear-gradient(135deg, #eb3349 0%, #f45c43 100%)"}; padding: 25px; border-radius: 10px; box-shadow: 0 4px 8px rgba(0,0,0,0.2);'>
<h3 style='color: white; margin-top: 0; font-size: 20px; text-shadow: 2px 2px 4px rgba(0,0,0,0.3);'>โœจ Result</h3>
<p style='font-size: 24px; line-height: 1.8; color: white; font-weight: bold; text-shadow: 1px 1px 2px rgba(0,0,0,0.5);'>
{"โœ…" if is_perfect else "โŒ"} <span style='background: rgba(0,0,0,0.3); padding: 5px 10px; border-radius: 5px;'>{proper_sum}</span> {"=" if is_perfect else "โ‰ "} <span style='background: rgba(0,0,0,0.3); padding: 5px 10px; border-radius: 5px;'>{n}</span>
</p>
<p style='font-size: 18px; color: white; line-height: 1.6; text-shadow: 1px 1px 2px rgba(0,0,0,0.5);'>
{"๐ŸŽ‰ <strong>PERFECT NUMBER!</strong> This is one of the rare perfect numbers!" if is_perfect else f"<strong>NOT PERFECT</strong><br/>{'The sum (<strong>' + str(proper_sum) + '</strong>) is greater than the number (<strong>' + str(n) + '</strong>)<br/>Excess: <strong>' + str(proper_sum - n) + '</strong>' if classification == 'Abundant' else 'The sum (<strong>' + str(proper_sum) + '</strong>) is less than the number (<strong>' + str(n) + '</strong>)<br/>Deficiency: <strong>' + str(n - proper_sum) + '</strong>'}"}
</p>
</div>
<div style='margin-top: 30px;'>
{MATHEMATICIANS}
</div>
</div>
"""
return msg, fig
# Create Gradio interface
with gr.Blocks(theme=gr.themes.Soft(), title="Perfect Number Explorer") as demo:
gr.Markdown("""
# ๐Ÿ”ข Perfect Number Visualizer & Explorer (Unlimited Range!)
### What are Perfect Numbers?
A **perfect number** is a positive integer that equals the sum of its proper divisors (divisors excluding the number itself).
**Example:** 6 is perfect because 1 + 2 + 3 = 6
### Try these perfect numbers: 6, 28, 496, 8128, 33550336
### Or try very large numbers like 2^31-1 (2147483647) or even larger!
""")
with gr.Row():
with gr.Column(scale=1):
number_input = gr.Number(
label="Enter ANY Positive Integer",
value=6,
precision=0
)
analyze_btn = gr.Button("๐Ÿ” Analyze Number", variant="primary", size="lg")
gr.Markdown("""
### Key Features:
- **Unlimited Range**: Analyze ANY positive integer (no upper limit!)
- **Optimized Algorithms**: Efficiently handles very large numbers
- **Interactive Visualizations**: Zoom, pan, and hover for details
- **Comprehensive Analysis**: Divisors, factorization, and classification
""")
with gr.Row():
result_text = gr.HTML(
label="๐Ÿ“Š Detailed Analysis"
)
with gr.Row():
plot_output = gr.Plot(label="๐Ÿ“ˆ Interactive Visual Analysis")
analyze_btn.click(
fn=create_enhanced_visualization,
inputs=number_input,
outputs=[result_text, plot_output]
)
# Auto-analyze on load
demo.load(
fn=create_enhanced_visualization,
inputs=number_input,
outputs=[result_text, plot_output]
)
if __name__ == "__main__":
demo.launch()