PromptWizardry / app.py
awacke1's picture
Update app.py
8bc23f8 verified
raw
history blame
15.4 kB
import streamlit as st
import pandas as pd
import random
import json
# Set page configuration
st.set_page_config(page_title="ChatGPT Prompt Generator", page_icon="๐Ÿง ", layout="wide")
# Custom CSS for styling
st.markdown("""
<style>
.main {background-color: #f8f9fa;}
div[data-testid="stVerticalBlock"] {gap: 0.2rem;}
div[data-testid="stHorizontalBlock"] {gap: 0.3rem;}
.stTextArea textarea, .stTextInput input {
padding: 0.3rem;
font-size: 0.85em;
}
h1, h2, h3 {margin-top: 0; margin-bottom: 0.2rem;}
p, div {margin-bottom: 0.1rem;}
.category-header {
font-weight: bold;
font-size: 1rem;
margin-bottom: 0.2rem;
color: #333;
background-color: #f1f8ff;
padding: 3px 8px;
border-radius: 4px;
}
.prompt-display {
background-color: #ffffff;
border-radius: 4px;
padding: 12px;
border: 1px solid #e9ecef;
min-height: 150px;
white-space: pre-wrap;
}
.st-emotion-cache-1nv1tyf {
font-size: 0.85rem;
}
.dataframe-container {
background-color: white;
border: 1px solid #e6e6e6;
border-radius: 4px;
padding: 8px;
margin-bottom: 8px;
}
.selected-item {
background-color: #007bff !important;
color: white !important;
font-weight: bold;
padding: 2px 6px;
border-radius: 4px;
}
.unselected-item {
background-color: #f8f9fa;
padding: 2px 6px;
border-radius: 4px;
cursor: pointer;
}
.unselected-item:hover {
background-color: #e9ecef;
}
table {
font-size: 0.85rem;
}
.clickable {
cursor: pointer;
}
</style>
""", unsafe_allow_html=True)
# Initialize session state
if 'selections' not in st.session_state:
st.session_state.selections = {
'role': None, 'tone': None, 'instruction': None, 'length': None,
'content_type': None, 'audience': None, 'format': None,
'about': "", 'inclusion': "", 'exclusion': "", 'input_data': ""
}
# Data sets with emoji and names
data = {
'roles': [
{"name": "Professional", "emoji": "๐Ÿ‘”"}, {"name": "Expert", "emoji": "๐Ÿง "},
{"name": "Friend", "emoji": "๐Ÿค"}, {"name": "Copywriter", "emoji": "โœ๏ธ"},
{"name": "Creative Writer", "emoji": "๐Ÿ–‹๏ธ"}, {"name": "Sales Coach", "emoji": "๐Ÿ’ผ"},
{"name": "Marketing Coach", "emoji": "๐Ÿ“Š"}, {"name": "Tech Consultant", "emoji": "๐Ÿ’ป"},
{"name": "Life Coach", "emoji": "๐Ÿง˜"}, {"name": "Data Analyst", "emoji": "๐Ÿ“ˆ"},
{"name": "Influencer", "emoji": "๐Ÿ“ฑ"}, {"name": "Language Tutor", "emoji": "๐Ÿ—ฃ๏ธ"},
{"name": "Fitness Trainer", "emoji": "๐Ÿ’ช"}, {"name": "Teacher", "emoji": "๐Ÿ‘จโ€๐Ÿซ"},
{"name": "Therapist", "emoji": "๐Ÿง"}, {"name": "Detective", "emoji": "๐Ÿ”"}
],
'tones': [
{"name": "Informative", "emoji": "โ„น๏ธ"}, {"name": "Inspirational", "emoji": "โœจ"},
{"name": "Humorous", "emoji": "๐Ÿ˜„"}, {"name": "Friendly", "emoji": "๐Ÿ˜Š"},
{"name": "Professional", "emoji": "๐Ÿ‘”"}, {"name": "Casual", "emoji": "๐Ÿ‘‹"},
{"name": "Persuasive", "emoji": "๐Ÿค"}, {"name": "Encouraging", "emoji": "๐Ÿ™Œ"},
{"name": "Empathetic", "emoji": "๐Ÿค—"}, {"name": "Serious", "emoji": "๐Ÿ˜"},
{"name": "Enthusiastic", "emoji": "๐Ÿคฉ"}, {"name": "Thoughtful", "emoji": "๐Ÿ’ญ"}
],
'instructions': [
{"name": "Create", "emoji": "๐Ÿ”จ"}, {"name": "Suggest", "emoji": "๐Ÿ’ก"},
{"name": "Write", "emoji": "โœ๏ธ"}, {"name": "Compose", "emoji": "๐Ÿ“"},
{"name": "Analyze", "emoji": "๐Ÿ”"}, {"name": "Explain", "emoji": "๐Ÿ“š"},
{"name": "Describe", "emoji": "๐Ÿ”Ž"}, {"name": "Summarize", "emoji": "๐Ÿ“‹"},
{"name": "Compare", "emoji": "โš–๏ธ"}, {"name": "Outline", "emoji": "๐Ÿ“‹"},
{"name": "Evaluate", "emoji": "โญ"}, {"name": "List", "emoji": "๐Ÿ“‹"}
],
'lengths': [
{"name": "300 Words", "emoji": "๐Ÿ“"}, {"name": "500 Words", "emoji": "๐Ÿ“„"},
{"name": "Short", "emoji": "๐Ÿฉณ"}, {"name": "Medium", "emoji": "๐Ÿ“Š"},
{"name": "Long", "emoji": "๐Ÿ“œ"}, {"name": "Brief", "emoji": "๐Ÿ’จ"},
{"name": "Detailed", "emoji": "๐Ÿ”Ž"}, {"name": "Comprehensive", "emoji": "๐Ÿ“š"}
],
'content_types': [
{"name": "Article", "emoji": "๐Ÿ“ฐ"}, {"name": "Blog post", "emoji": "๐Ÿ“"},
{"name": "Guide", "emoji": "๐Ÿ“š"}, {"name": "Email", "emoji": "๐Ÿ“ง"},
{"name": "Summary", "emoji": "๐Ÿ“‹"}, {"name": "Story", "emoji": "๐Ÿ“–"},
{"name": "Essay", "emoji": "๐Ÿ“„"}, {"name": "Review", "emoji": "โญ"},
{"name": "Tutorial", "emoji": "๐Ÿ‘จโ€๐Ÿซ"}, {"name": "Report", "emoji": "๐Ÿ“Š"},
{"name": "Plan", "emoji": "๐Ÿ“†"}, {"name": "Script", "emoji": "๐ŸŽฌ"}
],
'audiences': [
{"name": "Beginners", "emoji": "๐ŸŒฑ"}, {"name": "Experts", "emoji": "๐Ÿง "},
{"name": "Students", "emoji": "๐ŸŽ“"}, {"name": "Professionals", "emoji": "๐Ÿ‘”"},
{"name": "Business Owners", "emoji": "๐Ÿ’ผ"}, {"name": "General Public", "emoji": "๐Ÿ‘ฅ"},
{"name": "Developers", "emoji": "๐Ÿ’ป"}, {"name": "Children", "emoji": "๐Ÿ‘ถ"}
],
'formats': [
{"name": "Markdown", "emoji": "๐Ÿ“"}, {"name": "HTML", "emoji": "๐ŸŒ"},
{"name": "Plain Text", "emoji": "๐Ÿ“„"}, {"name": "JSON", "emoji": "๐Ÿ”„"},
{"name": "PDF", "emoji": "๐Ÿ“‘"}, {"name": "Python Code", "emoji": "๐Ÿ"},
{"name": "JavaScript", "emoji": "๐Ÿ“œ"}, {"name": "SQL Query", "emoji": "๐Ÿ’พ"}
]
}
# Function to convert data to dataframe rows
def create_dataframe_rows(items, cols=4):
# Calculate how many rows we need based on items and columns
num_rows = (len(items) + cols - 1) // cols
# Create empty rows
rows = [["" for _ in range(cols)] for _ in range(num_rows)]
# Fill in the values
for i, item in enumerate(items):
row_idx = i // cols
col_idx = i % cols
rows[row_idx][col_idx] = f"{item['emoji']} {item['name']}"
return rows
# Function to handle cell click events
def handle_selection(category, value):
# Extract the name without emoji
parts = value.split(' ', 1)
if len(parts) < 2:
return
emoji = parts[0]
name = parts[1]
# Find the item in the data
for item in data[f"{category}s"]:
if item['name'] == name:
st.session_state.selections[category] = item
return
# If not found (shouldn't happen)
st.session_state.selections[category] = {"name": name, "emoji": emoji}
# Function to create dataframe with click handler
def create_dataframe_category(category, title, emoji_prefix):
# Create the dataframe content
df_rows = create_dataframe_rows(data[f"{category}s"], cols=4)
df = pd.DataFrame(df_rows)
# Display the category header
st.markdown(f"<div class='category-header'>{emoji_prefix} {title}</div>", unsafe_allow_html=True)
# Display in a container
st.markdown(f"<div class='dataframe-container'>", unsafe_allow_html=True)
# Use an edited dataframe
edited_df = st.data_editor(
df,
key=f"df_{category}",
hide_index=True,
column_config={
i: st.column_config.Column(
label=f"Option {i+1}",
width="small",
) for i in range(df.shape[1])
},
disabled=True,
use_container_width=True,
on_click=lambda e: handle_selection(category, e.current)
)
# Check if there's a selected value to highlight
if st.session_state.selections[category]:
selected_value = f"{st.session_state.selections[category]['emoji']} {st.session_state.selections[category]['name']}"
# Since we can't style specific cells in the dataframe editor, we can indicate the selection another way
selected_index = None
for i, row in df.iterrows():
for j, cell in enumerate(row):
if cell == selected_value:
selected_index = (i, j)
break
if selected_index:
break
if selected_index:
st.markdown(f"Selected: **{selected_value}**", unsafe_allow_html=True)
st.markdown("</div>", unsafe_allow_html=True)
# Function to generate the final prompt
def generate_prompt():
sel = st.session_state.selections
# Check if all required fields are selected
if not all([sel['role'], sel['tone'], sel['instruction'], sel['length'],
sel['content_type'], sel['audience'], sel['format'], sel['about']]):
return "Please select all required components and provide a topic."
# Generate the prompt
prompt = f"""Act as a {sel['role']['emoji']} {sel['role']['name']}, use {sel['tone']['emoji']} {sel['tone']['name']} tone, {sel['instruction']['emoji']} {sel['instruction']['name']} a {sel['length']['emoji']} {sel['length']['name']} {sel['content_type']['emoji']} {sel['content_type']['name']} for {sel['audience']['emoji']} {sel['audience']['name']}.
It should be about {sel['about']}."""
if sel['inclusion']:
prompt += f"\nInclude {sel['inclusion']}."
if sel['exclusion']:
prompt += f"\nExclude {sel['exclusion']}."
prompt += f"\n\nReturn the output as {sel['format']['emoji']} {sel['format']['name']}."
if sel['input_data']:
prompt += f"\nUse the following information: {sel['input_data']}"
return prompt
# Header
st.markdown("<h2 style='text-align: center; font-size: 1.3rem; margin-bottom: 1rem;'>๐Ÿง  ChatGPT Prompt Generator</h2>", unsafe_allow_html=True)
# Main layout with two columns
col1, col2 = st.columns([3, 1])
with col1:
# Create dataframes for each category
create_dataframe_category("role", "Choose a Role", "๐Ÿ‘ค")
create_dataframe_category("tone", "Select a Tone", "๐ŸŽญ")
create_dataframe_category("instruction", "Select an Instruction", "๐Ÿ“")
create_dataframe_category("length", "Select Length", "๐Ÿ“")
create_dataframe_category("content_type", "Select Content Type", "๐Ÿ“„")
create_dataframe_category("audience", "Select Target Audience", "๐Ÿ‘ฅ")
create_dataframe_category("format", "Select Format", "๐Ÿ“‹")
# Text input fields
st.markdown("<div class='category-header'>๐Ÿ“Œ Additional Details</div>", unsafe_allow_html=True)
st.markdown("<div class='dataframe-container'>", unsafe_allow_html=True)
st.session_state.selections['about'] = st.text_input("๐Ÿ’ฌ Topic",
value=st.session_state.selections['about'],
placeholder="Enter what the content should be about")
col1, col2 = st.columns(2)
with col1:
st.session_state.selections['inclusion'] = st.text_input("โœ… Include",
value=st.session_state.selections['inclusion'],
placeholder="What to include in the content")
with col2:
st.session_state.selections['exclusion'] = st.text_input("โŒ Exclude",
value=st.session_state.selections['exclusion'],
placeholder="What to exclude from the content")
st.session_state.selections['input_data'] = st.text_area("๐Ÿ“Š Input Data",
value=st.session_state.selections['input_data'],
placeholder="Enter any specific information to use",
height=100)
st.markdown("</div>", unsafe_allow_html=True)
with col2:
# Generate the prompt
prompt = generate_prompt()
# Display the prompt
st.markdown("<div class='category-header'>๐Ÿ”ฎ Generated Prompt</div>", unsafe_allow_html=True)
st.markdown("<div class='dataframe-container'>", unsafe_allow_html=True)
st.markdown("<div class='prompt-display'>", unsafe_allow_html=True)
st.write(prompt)
st.markdown("</div>", unsafe_allow_html=True)
# Action buttons
btn1, btn2, btn3 = st.columns(3)
with btn1:
if st.button("๐Ÿ“‹ Copy", type="primary", use_container_width=True):
st.code(prompt, language="")
with btn2:
if st.button("๐Ÿ”„ Reset", type="secondary", use_container_width=True):
for key in st.session_state.selections:
if key in ['about', 'inclusion', 'exclusion', 'input_data']:
st.session_state.selections[key] = ""
else:
st.session_state.selections[key] = None
st.experimental_rerun()
with btn3:
if st.button("๐ŸŽฒ Random", type="secondary", use_container_width=True):
for category in ['role', 'tone', 'instruction', 'length', 'content_type', 'audience', 'format']:
st.session_state.selections[category] = random.choice(data[category+'s'])
st.experimental_rerun()
st.markdown("</div>", unsafe_allow_html=True)
# Sample prompts section
st.markdown("<div class='category-header'>๐Ÿ“š Examples</div>", unsafe_allow_html=True)
st.markdown("<div class='dataframe-container'>", unsafe_allow_html=True)
# Example 1
st.markdown("""
<div style="background-color: #e6f3ff; border: 1px solid #b8daff; border-radius: 4px; padding: 6px; margin-bottom: 6px; font-size: 0.8em;">
<b>๐Ÿ‘จโ€๐Ÿซ Teaching</b><pre style="white-space: pre-wrap; font-size: 0.8em; margin: 3px 0px;">Act as a ๐Ÿ‘จโ€๐Ÿซ Teacher, use ๐Ÿ“š Informative tone, Create a ๐Ÿ“‹ Guide for ๐ŸŒฑ Beginners.
It should be about Git.
Include practical examples.
Exclude advanced techniques.
Return as ๐Ÿ“ Markdown.</pre>
</div>
""", unsafe_allow_html=True)
# Example 2
st.markdown("""
<div style="background-color: #e6ffed; border: 1px solid #b8e6cc; border-radius: 4px; padding: 6px; margin-bottom: 6px; font-size: 0.8em;">
<b>๐Ÿ’ผ Business</b><pre style="white-space: pre-wrap; font-size: 0.8em; margin: 3px 0px;">Act as a ๐Ÿ‘” Professional, use ๐Ÿค Persuasive tone, Write a ๐Ÿ“ง Email for ๐Ÿ‘ฉโ€๐Ÿ’ผ Executives.
It should be about a product launch.
Include ROI metrics.
Exclude technical details.
Return as ๐Ÿ“„ Plain Text.</pre>
</div>
""", unsafe_allow_html=True)
# Prompt structure guide
st.markdown("""
<div style="background-color: #f1f8ff; border-radius: 4px; padding: 6px; margin-top: 6px; font-size: 0.8em;">
<b>Prompt Structure:</b><br>
Act as [<span style="color:blue">ROLE</span>], use [<span style="color:green">TONE</span>] tone, [<span style="color:red">INSTRUCTION</span>] a [<span style="color:purple">LENGTH</span>] [<span style="color:orange">CONTENT TYPE</span>] for [<span style="color:pink">AUDIENCE</span>].<br>
It should be about [TOPIC].<br>
Include [INCLUSION]. Exclude [EXCLUSION].<br>
Return as [FORMAT].
</div>
""", unsafe_allow_html=True)
st.markdown("</div>", unsafe_allow_html=True)