diff --git a/Dream Journal Calculator/README.md b/Dream Journal Calculator/README.md new file mode 100644 index 00000000..1969c52b --- /dev/null +++ b/Dream Journal Calculator/README.md @@ -0,0 +1,58 @@ +# Dream Journal Calculator + +The Dream Journal Calculator is a web application that allows users to record their dreams, analyze the content, and visualize the emotions associated with the dream. It also provides a sentiment analysis to determine whether the dream was positive or negative. + +## Features + +- Record dream entries with title, date, description, and emotions. +- Generate a word cloud from the dream description. +- Analyze and display recurring words and emotions. +- Sentiment analysis to determine the positivity or negativity of the dream. +- Categorize the dream based on specific keywords. +- Store and display past dreams. +- Reset button to clear the form and results. + +## Input Fields + +1. **Dream Title**: A short title for the dream. +2. **Date**: The date when the dream occurred. +3. **Dream Entry**: A detailed description of the dream. +4. **Emotions**: Comma-separated list of emotions felt during the dream. + +## Output + +1. **Word Cloud**: Visual representation of the most frequently occurring words in the dream description. +2. **Recurring Words**: List of words that appear multiple times in the dream description. +3. **Emotions**: List of emotions associated with the dream. +4. **Sentiment Analysis**: Displays whether the dream is positive, negative, or neutral. +5. **Sentiment Bar**: Visual bar showing the percentage of positive and negative words in the dream. +6. **Category**: Categorization of the dream based on specific keywords. +7. **Past Dreams**: List of previously recorded dreams with details. + +## How to Use + +1. Fill in the form with your dream details: + - **Dream Title**: Enter a title for your dream. + - **Date**: Select the date of the dream. + - **Dream Entry**: Write a detailed description of your dream. + - **Emotions**: List the emotions you felt during the dream, separated by commas. + +2. Click the "Analyze Dream" button to analyze your dream. + +3. View the results: + - The word cloud will display the most frequently occurring words in your dream description. + - Recurring words and emotions will be listed below the word cloud. + - Sentiment analysis will show whether the dream is positive, negative, or neutral. + - A sentiment bar will visually represent the percentage of positive and negative words. + - The category of the dream will be displayed based on specific keywords. + - Past dreams will be listed below the analysis. + +4. Click the "Reset" button to clear the form and results. + +## Technologies Used + +- HTML +- CSS +- JavaScript +- WordCloud2.js (for generating word clouds) + diff --git a/Dream Journal Calculator/index.html b/Dream Journal Calculator/index.html new file mode 100644 index 00000000..bd3a7592 --- /dev/null +++ b/Dream Journal Calculator/index.html @@ -0,0 +1,35 @@ + + + + + + Dream Journal Calculator + + + + +
+

Dream Journal Calculator

+
+ + + + + + + + + + +
+

Word Cloud

+
+

Analysis

+
+

Past Dreams

+
+
+ + + + diff --git a/Dream Journal Calculator/manifest.json b/Dream Journal Calculator/manifest.json new file mode 100644 index 00000000..0c4027c3 --- /dev/null +++ b/Dream Journal Calculator/manifest.json @@ -0,0 +1,21 @@ +{ + "name": "Dream Journal Calculator", + "short_name": "DreamCalc", + "start_url": "/", + "display": "standalone", + "background_color": "#ffffff", + "theme_color": "#007BFF", + "description": "A web app for analyzing dream journal entries.", + "icons": [ + { + "src": "images/icon-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "images/icon-512x512.png", + "sizes": "512x512", + "type": "image/png" + } + ] +} diff --git a/Dream Journal Calculator/script.js b/Dream Journal Calculator/script.js new file mode 100644 index 00000000..d95b95a4 --- /dev/null +++ b/Dream Journal Calculator/script.js @@ -0,0 +1,158 @@ +document.getElementById('dreamForm').addEventListener('submit', function(event) { + event.preventDefault(); + + const title = document.getElementById('dreamTitle').value; + const date = document.getElementById('dreamDate').value; + const entry = document.getElementById('dreamEntry').value; + const emotions = document.getElementById('dreamEmotions').value.split(',').map(e => e.trim()); + + const words = extractKeywords(entry); + displayWordCloud(words); + displayAnalysis(words, emotions, entry); + + storeDream({ title, date, entry, emotions }); + displayPastDreams(); +}); + +document.getElementById('resetButton').addEventListener('click', function() { + document.getElementById('dreamForm').reset(); + document.getElementById('wordCloud').innerHTML = ''; + document.getElementById('analysis').innerHTML = ''; +}); + +function extractKeywords(text) { + const stopwords = ["I", "was", "and", "the", "a", "to", "in", "of", "that", "it"]; + const words = text.split(/\W+/).filter(word => !stopwords.includes(word.toLowerCase())); + const wordCount = {}; + + words.forEach(word => { + word = word.toLowerCase(); + wordCount[word] = (wordCount[word] || 0) + 1; + }); + + return Object.entries(wordCount).map(([word, size]) => ({ word, size })); +} + +function displayWordCloud(words) { + const wordCloudData = words.map(({ word, size }) => [word, size * 10]); + WordCloud(document.getElementById('wordCloud'), { list: wordCloudData }); +} + +function displayAnalysis(words, emotions, entry) { + const analysisDiv = document.getElementById('analysis'); + analysisDiv.innerHTML = ''; + + const recurringWords = words.filter(({ size }) => size > 1).map(({ word }) => word); + const emotionList = emotions.join(', '); + + const recurringWordsElement = document.createElement('p'); + recurringWordsElement.textContent = `Recurring words: ${recurringWords.join(', ')}`; + analysisDiv.appendChild(recurringWordsElement); + + const emotionElement = document.createElement('p'); + emotionElement.textContent = `Emotions: ${emotionList}`; + analysisDiv.appendChild(emotionElement); + + const sentiment = analyzeSentiment(entry); + const sentimentElement = document.createElement('p'); + sentimentElement.textContent = `Sentiment: ${sentiment.text}`; + analysisDiv.appendChild(sentimentElement); + + const category = categorizeDream(entry); + const categoryElement = document.createElement('p'); + categoryElement.textContent = `Category: ${category}`; + analysisDiv.appendChild(categoryElement); + + const sentimentBar = document.createElement('div'); + sentimentBar.className = 'sentiment-bar'; + sentimentBar.innerHTML = `
+ ${sentiment.positivePercentage.toFixed(1)}% +
+
+ ${sentiment.negativePercentage.toFixed(1)}% +
`; + analysisDiv.appendChild(sentimentBar); +} + +function analyzeSentiment(text) { + const positiveWords = ["happy", "joy", "excited", "love"]; + const negativeWords = ["sad", "angry", "fear", "hate"]; + let score = 0; + let positiveCount = 0; + let negativeCount = 0; + + text.split(/\W+/).forEach(word => { + if (positiveWords.includes(word.toLowerCase())) { + score++; + positiveCount++; + } + if (negativeWords.includes(word.toLowerCase())) { + score--; + negativeCount++; + } + }); + + const total = positiveCount + negativeCount; + const positivePercentage = total ? (positiveCount / total) * 100 : 0; + const negativePercentage = total ? (negativeCount / total) * 100 : 0; + + return { + text: score > 0 ? 'Positive' : score < 0 ? 'Negative' : 'Neutral', + positivePercentage, + negativePercentage + }; +} + +function categorizeDream(text) { + const keywords = { + "Adventure": ["explore", "travel", "journey"], + "Nightmare": ["chase", "fear", "dark"], + "Fantasy": ["magic", "fly", "unicorn"], + }; + + for (const [category, words] of Object.entries(keywords)) { + if (words.some(word => text.toLowerCase().includes(word))) { + return category; + } + } + + return "Uncategorized"; +} + +function storeDream(dream) { + const dreams = JSON.parse(localStorage.getItem('dreams')) || []; + dreams.push(dream); + localStorage.setItem('dreams', JSON.stringify(dreams)); +} + +function displayPastDreams() { + const dreams = JSON.parse(localStorage.getItem('dreams')) || []; + const pastDreamsDiv = document.getElementById('pastDreams'); + pastDreamsDiv.innerHTML = ''; + + dreams.forEach(dream => { + const dreamElement = document.createElement('div'); + dreamElement.classList.add('dream'); + + const titleElement = document.createElement('h3'); + titleElement.textContent = dream.title; + dreamElement.appendChild(titleElement); + + const dateElement = document.createElement('p'); + dateElement.textContent = `Date: ${dream.date}`; + dreamElement.appendChild(dateElement); + + const entryElement = document.createElement('p'); + entryElement.textContent = dream.entry; + dreamElement.appendChild(entryElement); + + const emotionsElement = document.createElement('p'); + emotionsElement.textContent = `Emotions: ${dream.emotions.join(', ')}`; + dreamElement.appendChild(emotionsElement); + + pastDreamsDiv.appendChild(dreamElement); + }); +} + +// Load past dreams on page load +document.addEventListener('DOMContentLoaded', displayPastDreams); diff --git a/Dream Journal Calculator/styles.css b/Dream Journal Calculator/styles.css new file mode 100644 index 00000000..d9d2446c --- /dev/null +++ b/Dream Journal Calculator/styles.css @@ -0,0 +1,83 @@ +body { + font-family: Arial, sans-serif; + background-color: #f0f0f0; + color: #333; +} + +.container { + width: 80%; + margin: 0 auto; + padding: 20px; + background-color: #fff; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); +} + +h1, h2 { + text-align: center; +} + +form { + display: flex; + flex-direction: column; + margin-bottom: 20px; +} + +label { + margin-top: 10px; +} + +input, textarea, button { + padding: 10px; + margin-top: 5px; +} + +button { + background-color: #007BFF; + color: white; + border: none; + cursor: pointer; + margin-top: 20px; +} + +button:hover { + background-color: #0056b3; +} + +#wordCloud { + margin: 0 auto; +} + +.dream { + border-bottom: 1px solid #ccc; + padding: 10px 0; +} + +.dream h3 { + margin: 0; +} + +.dream p { + margin: 5px 0; +} + +.sentiment-bar { + display: flex; + height: 20px; + margin-top: 10px; + position: relative; + background-color: #e0e0e0; +} + +.sentiment-positive { + background-color: green; + text-align: center; + color: white; + line-height: 20px; +} + +.sentiment-negative { + background-color: red; + text-align: center; + color: white; + line-height: 20px; +}