From cf6e98d00a16a66be5204ebd2212da87b30979d3 Mon Sep 17 00:00:00 2001 From: sunil834 Date: Sun, 23 Jun 2024 20:06:25 +0530 Subject: [PATCH 1/8] Task 1 Completed. --- N.Sunil-Easy/web_scrapper.py | 84 ++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 N.Sunil-Easy/web_scrapper.py diff --git a/N.Sunil-Easy/web_scrapper.py b/N.Sunil-Easy/web_scrapper.py new file mode 100644 index 0000000..ce554d6 --- /dev/null +++ b/N.Sunil-Easy/web_scrapper.py @@ -0,0 +1,84 @@ +# Web Scraping Tool with BeautifulSoup +'''Develop a web scraping application using Python's BeautifulSoup library. +Extract data from a website and present it in a structured format (e.g., CSV, JSON). +''' + +# Required Modules +import requests +from bs4 import BeautifulSoup +import csv +import json + +# Fetching URL +url = 'https://www.imdb.com/chart/top/' + +# Using headers to prevent boting +headers = { + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' +} + +# Converting Json to HTML +def js_to_html(html_content): + soup = BeautifulSoup(html_content, 'html.parser') + scripts = soup.find_all('script') + + for script in scripts: + if script.get('type') == 'application/ld+json': + return script.string + return None + +# Extracting the top 250 iMDB movie details from the url +def extract_movie_data(json_data): + movies = [] + + for item in json_data.get('itemListElement', []): + movie = item.get('item', {}) + name = movie.get('name') + description = movie.get('description') + rating_value = movie.get('aggregateRating', {}).get('ratingValue') + content_rating = movie.get('contentRating') + genre = movie.get('genre') + movies.append({ + 'name': name, + 'description': description, + 'ratingValue': rating_value, + 'contentRating': content_rating, + 'genre': genre + }) + return movies + +# Fetching url +try: + response = requests.get(url, headers=headers) + response.raise_for_status() + json_string = js_to_html(response.content) + + #Checking the presense of json in the HTML content + if not json_string: + print("JSON data not found in the HTML content.") + + else: + json_data = json.loads(json_string) + movies = extract_movie_data(json_data) + print(f"Extracted {len(movies)} movies.") + csv_file_name = 'imdb_top_250.csv' + + # Saving fetchd data into .csv file + with open(csv_file_name, 'w', newline='', encoding='utf-8') as csvfile: + fieldnames = ['name', 'description', 'ratingValue', 'contentRating', 'genre'] + writer = csv.DictWriter(csvfile, fieldnames=fieldnames) + writer.writeheader() + writer.writerows(movies) + print(f"Data saved to '{csv_file_name}'.") + json_file_name = 'imdb_top_250.json' + + # Saving fetchd data into .json file + with open(json_file_name, 'w', encoding='utf-8') as jsonfile: + json.dump(movies, jsonfile, ensure_ascii=False, indent=4) + print(f"Data saved to '{json_file_name}'.") + +# Exception catching in the request +except requests.exceptions.HTTPError as http_err: + print(f"HTTP error occurred: {http_err}") +except Exception as err: + print(f"Other error occurred: {err}") \ No newline at end of file From 65ce883d8c17ff23902ff8350ff61b083c9e0cf4 Mon Sep 17 00:00:00 2001 From: sunil834 Date: Mon, 15 Jul 2024 20:55:29 +0530 Subject: [PATCH 2/8] Improved Comments --- N.Sunil-Easy/web_scrapper.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/N.Sunil-Easy/web_scrapper.py b/N.Sunil-Easy/web_scrapper.py index ce554d6..2b831d7 100644 --- a/N.Sunil-Easy/web_scrapper.py +++ b/N.Sunil-Easy/web_scrapper.py @@ -1,8 +1,4 @@ # Web Scraping Tool with BeautifulSoup -'''Develop a web scraping application using Python's BeautifulSoup library. -Extract data from a website and present it in a structured format (e.g., CSV, JSON). -''' - # Required Modules import requests from bs4 import BeautifulSoup From 2781fde0758fbd4a9a322d171fc8266a4954a744 Mon Sep 17 00:00:00 2001 From: sunil834 Date: Mon, 15 Jul 2024 21:09:12 +0530 Subject: [PATCH 3/8] Completed task2 --- N.Sunil-Easy/nltk_chatbot.py | 51 ++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 N.Sunil-Easy/nltk_chatbot.py diff --git a/N.Sunil-Easy/nltk_chatbot.py b/N.Sunil-Easy/nltk_chatbot.py new file mode 100644 index 0000000..4a62aac --- /dev/null +++ b/N.Sunil-Easy/nltk_chatbot.py @@ -0,0 +1,51 @@ +# Basic Chatbot with NLTK +# Required Modules +import nltk +from nltk.chat.util import Chat, reflections + +# Pairs +pairs = [ + [ + r"hi|hello|hey", + ["Hello!", "Hi there!", "Hey!"] + ], + [ + r"how are you?", + ["I'm good, thank you! How about you?", "Doing well, how are you?"] + ], + [ + r"what is your name?", + ["I'm a chatbot created using NLTK.", "You can call me NLTKBot."] + ], + [ + r"what can you do?", + ["I can chat with you and answer some basic questions.", "I'm here to talk and help you with basic queries."] + ], + [ + r"how does natural language processing work?", + ["Natural Language Processing (NLP) is a field of artificial intelligence that focuses on the interaction between computers and humans through natural language.", + "NLP combines computational linguistics with statistical, machine learning, and deep learning models to process and understand human language."] + ], + [ + r"(.*) your favorite (.*)?", + ["I'm just a bot, but I think everything is interesting!", "I don't have preferences, but I enjoy learning new things!"] + ], + [ + r"quit", + ["Bye for now. See you soon!", "Goodbye! It was nice talking to you."] + ], + [ + r"(.*)", + ["I'm sorry, I don't understand that. Can you please rephrase?", "Can you please clarify your question?"] + ] +] + +# Converse ChatBot +def chatbot(): + print("Hi! I'm a chatbot created using NLTK. Type 'quit' to exit.") + chat = Chat(pairs, reflections) + chat.converse() + +# Start ChatBot +if __name__ == "__main__": + chatbot() From 2ef9277b6baef32c2bc4f86e221e852fca966d03 Mon Sep 17 00:00:00 2001 From: sunil834 Date: Mon, 15 Jul 2024 21:59:56 +0530 Subject: [PATCH 4/8] Completed Task4 --- N.Sunil-Easy/audio_recorder.py | 121 +++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 N.Sunil-Easy/audio_recorder.py diff --git a/N.Sunil-Easy/audio_recorder.py b/N.Sunil-Easy/audio_recorder.py new file mode 100644 index 0000000..85d1c53 --- /dev/null +++ b/N.Sunil-Easy/audio_recorder.py @@ -0,0 +1,121 @@ +import pyaudio +import wave +import soundfile as sf +from pydub import AudioSegment + +# Basic Params +FORMAT = pyaudio.paInt16 +CHANNELS = 2 +RATE = 44100 +CHUNK = 1024 +RECORD_SECONDS = 5 +WAVE_OUTPUT_FILENAME = "output.wav" + +# Record audio +def record_audio(filename=WAVE_OUTPUT_FILENAME, record_seconds=RECORD_SECONDS): + audio = pyaudio.PyAudio() + + # Start Recording + stream = audio.open(format=FORMAT, channels=CHANNELS, + rate=RATE, input=True, + frames_per_buffer=CHUNK) + print("Recording...") + + frames = [] + + try: + for _ in range(0, int(RATE / CHUNK * record_seconds)): + data = stream.read(CHUNK) + frames.append(data) + except Exception as e: + print(f"An error occurred while recording: {e}") + finally: + print("Finished recording.") + + # Stop Recording + stream.stop_stream() + stream.close() + audio.terminate() + + # Save the recording + wf = wave.open(filename, 'wb') + wf.setnchannels(CHANNELS) + wf.setsampwidth(audio.get_sample_size(FORMAT)) + wf.setframerate(RATE) + wf.writeframes(b''.join(frames)) + wf.close() + +# Audio Playback +def playback_audio(filename=WAVE_OUTPUT_FILENAME): + wf = wave.open(filename, 'rb') + + audio = pyaudio.PyAudio() + + # Open stream + stream = audio.open(format=audio.get_format_from_width(wf.getsampwidth()), + channels=wf.getnchannels(), + rate=wf.getframerate(), + output=True) + + # Read data in chunks + data = wf.readframes(CHUNK) + + print("Playing back...") + try: + while data: + stream.write(data) + data = wf.readframes(CHUNK) + except Exception as e: + print(f"An error occurred during playback: {e}") + finally: + # Stop stream + stream.stop_stream() + stream.close() + audio.terminate() + print("Playback finished.") + +# Save audio in different formats +def save_audio_in_format(input_filename=WAVE_OUTPUT_FILENAME, output_filename="output.flac", output_format="FLAC"): + try: + if output_format.lower() == 'mp3': + audio = AudioSegment.from_wav(input_filename) + audio.export(output_filename, format="mp3") + else: + data, samplerate = sf.read(input_filename) + sf.write(output_filename, data, samplerate, format=output_format) + print(f"Audio saved in {output_format} format as {output_filename}") + except Exception as e: + print(f"An error occurred while saving the audio: {e}") + +# Main function +def main(): + while True: + print("\nVoice Recording Application") + print("1. Record Audio") + print("2. Playback Audio") + print("3. Save Audio in Different Format") + print("4. Exit") + + choice = input("Enter your choice: ") + + if choice == '1': + try: + duration = int(input("Enter duration in seconds: ")) + record_audio(record_seconds=duration) + except ValueError: + print("Invalid input. Please enter a number.") + elif choice == '2': + playback_audio() + elif choice == '3': + format_choice = input("Enter the format to save (e.g., FLAC, MP3): ").upper() + output_filename = input("Enter the output filename (including extension): ") + save_audio_in_format(output_filename=output_filename, output_format=format_choice) + elif choice == '4': + print("Exiting...") + break + else: + print("Invalid choice. Please try again.") + +# Start +if __name__ == "__main__": + main() \ No newline at end of file From 90d53af0afda43f624ee53c935b96500f80ba910 Mon Sep 17 00:00:00 2001 From: sunil834 Date: Mon, 15 Jul 2024 22:02:42 +0530 Subject: [PATCH 5/8] Imporved Comments --- N.Sunil-Easy/audio_recorder.py | 2 ++ N.Sunil-Easy/nltk_chatbot.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/N.Sunil-Easy/audio_recorder.py b/N.Sunil-Easy/audio_recorder.py index 85d1c53..4bbb64c 100644 --- a/N.Sunil-Easy/audio_recorder.py +++ b/N.Sunil-Easy/audio_recorder.py @@ -1,3 +1,5 @@ +#Voice Recorder with PyAudio +# Required Modules import pyaudio import wave import soundfile as sf diff --git a/N.Sunil-Easy/nltk_chatbot.py b/N.Sunil-Easy/nltk_chatbot.py index 4a62aac..1694119 100644 --- a/N.Sunil-Easy/nltk_chatbot.py +++ b/N.Sunil-Easy/nltk_chatbot.py @@ -3,7 +3,7 @@ import nltk from nltk.chat.util import Chat, reflections -# Pairs +# Pairs:Reflections pairs = [ [ r"hi|hello|hey", From 87ba9d4af99dab40c5452453728ef4036da4a11e Mon Sep 17 00:00:00 2001 From: sunil834 Date: Sun, 21 Jul 2024 22:56:20 +0530 Subject: [PATCH 6/8] Updated Files --- N.Sunil-Easy/{ => Task 1}/web_scrapper.py | 0 N.Sunil-Easy/{ => Task 2}/nltk_chatbot.py | 0 N.Sunil-Easy/Task 3/db.sqlite | Bin 0 -> 8192 bytes N.Sunil-Easy/Task 3/instance/db.sqlite | Bin 0 -> 8192 bytes N.Sunil-Easy/Task 3/static/style.css | 160 ++++++++++++++++++++ N.Sunil-Easy/Task 3/task_manager.py | 44 ++++++ N.Sunil-Easy/Task 3/templates/base.html | 47 ++++++ N.Sunil-Easy/{ => Task 4}/audio_recorder.py | 0 8 files changed, 251 insertions(+) rename N.Sunil-Easy/{ => Task 1}/web_scrapper.py (100%) rename N.Sunil-Easy/{ => Task 2}/nltk_chatbot.py (100%) create mode 100644 N.Sunil-Easy/Task 3/db.sqlite create mode 100644 N.Sunil-Easy/Task 3/instance/db.sqlite create mode 100644 N.Sunil-Easy/Task 3/static/style.css create mode 100644 N.Sunil-Easy/Task 3/task_manager.py create mode 100644 N.Sunil-Easy/Task 3/templates/base.html rename N.Sunil-Easy/{ => Task 4}/audio_recorder.py (100%) diff --git a/N.Sunil-Easy/web_scrapper.py b/N.Sunil-Easy/Task 1/web_scrapper.py similarity index 100% rename from N.Sunil-Easy/web_scrapper.py rename to N.Sunil-Easy/Task 1/web_scrapper.py diff --git a/N.Sunil-Easy/nltk_chatbot.py b/N.Sunil-Easy/Task 2/nltk_chatbot.py similarity index 100% rename from N.Sunil-Easy/nltk_chatbot.py rename to N.Sunil-Easy/Task 2/nltk_chatbot.py diff --git a/N.Sunil-Easy/Task 3/db.sqlite b/N.Sunil-Easy/Task 3/db.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..c712ec349041d52df4f2a09290de3663767fa394 GIT binary patch literal 8192 zcmeI%!Aiq07zglVR<{mDr7(8z@*P(Yne5=fi`^_b>{{)ru#QF2w%h$+}WEK{~!5CzO)J9cT6UCZXyLO@?srH>a#<}IlCZYjF~EHDtE!vK-(3n zuj=2zWGDV>OZ~--7p58l0uX=z1Rwwb2tWV=5P$##An@M=wl!YwwA*~Ul+i2|GLQ2r zYs0{?Lx)0p;5t;zP`9besC;@%Vj6j&bL9l&`5}4tu6s;PJ&V?Y9_(OvZ3o@cUeBr~ z<2(~I@O{^@y{f(qMq@je(v35v?$2&k(`p$XOf%k?@nyUlpK5@B00bZa0SG_<0uX=z z1Rwwb2teR31v&>B>o>+iNGj*6JWpv+BqEDTb5CQIo{Ff*C=(l!V!l!btDiN-=DzyW lxD;iw%xEKKrFz^y;u<^GCu${$b(Ey)PJ!lms@5-`#W(E5O@ROa literal 0 HcmV?d00001 diff --git a/N.Sunil-Easy/Task 3/instance/db.sqlite b/N.Sunil-Easy/Task 3/instance/db.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..ab4507efcaa3c17eaeb6c4e08078ea165db754c3 GIT binary patch literal 8192 zcmeI#K}*9h6bJC67Tk&&FT<1YytN=Q@eA0EFo(6(ScRP=CG8w_E7;PDr=9(hvX9^= zFa>w^?*5NFlJ^LK{Bp|UL$qjeDysLTZs>{~GtSvH5o1i)bZl;e+l9L=?A+CVgeW!&Fil zjv`52hkUQ!=(>Da7@EeZoJd7+l2ZH>Md#%8S9+P#bEw8Qq4F<>!=P)LYL(L{Ng^4> zU45^nccGfmt(=knds^TH-QV018z#QRMttqs6X3oOfB*y_009U<00Izz00bZaf&U@k d?HxHTJL{RY$mXW43w^*{cG`O_GgBH}{{Z+ZI6wdZ literal 0 HcmV?d00001 diff --git a/N.Sunil-Easy/Task 3/static/style.css b/N.Sunil-Easy/Task 3/static/style.css new file mode 100644 index 0000000..90b9edd --- /dev/null +++ b/N.Sunil-Easy/Task 3/static/style.css @@ -0,0 +1,160 @@ +/* General Styles */ +body { + font-family: 'Roboto', sans-serif; + background-color: #f4f4f4; + margin: 0; + padding: 0; +} + +.container { + max-width: 800px; + margin: 50px auto; + padding: 20px; + background-color: #fff; + box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1); + border-radius: 8px; + transition: transform 0.2s ease-in-out; +} + +.container:hover { + transform: scale(1.02); +} + +h1 { + text-align: center; + color: #cc0000; + font-size: 2.5em; + margin-bottom: 20px; + text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1); +} + +/* Form Styles */ +.form-container { + display: flex; + justify-content: center; + margin-bottom: 20px; +} + +.form-group { + display: flex; + align-items: center; +} + +.thick { + font-weight: bold; + font-size: 1.2em; + margin-right: 10px; +} + +.input-task { + width: 60%; + padding: 10px; + border: 1px solid #ccc; + border-radius: 4px; + margin-right: 10px; + transition: border-color 0.3s; +} + +.input-task:focus { + border-color: #007bff; + box-shadow: 0 0 8px rgba(0, 123, 255, 0.3); +} + +/* Button Styles */ +.button1, .button2, .button3 { + padding: 10px 15px; + border: none; + border-radius: 4px; + cursor: pointer; + text-decoration: none; + color: #fff; + transition: background-color 0.3s, box-shadow 0.3s; +} + +.button1 { + background-color: #28a745; + font-weight: bold; + font-size: 16px; +} + +.button1:hover { + background-color: #218838; + box-shadow: 0 4px 8px rgba(40, 167, 69, 0.3); +} + +.button2 { + background-color: #007bff; + font-weight: bold; + line-height: 25px; +} + +.button2:hover { + background-color: #0056b3; + box-shadow: 0 4px 8px rgba(0, 123, 255, 0.3); +} + +.button3 { + background-color: #dc3545; + font-weight: bold; + line-height: 25px; +} + +.button3:hover { + background-color: #c82333; + box-shadow: 0 4px 8px rgba(220, 53, 69, 0.3); +} + +/* Label Styles */ +.label { + color: white; + padding: 8px; + font-family: Arial, sans-serif; + border-radius: 4px; + text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.1); +} + +.done { + background-color: #28a745; +} + +.pending { + background-color: #ffc107; +} + +/* Table Styles */ +.task-table { + width: 100%; + border-collapse: collapse; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + margin-bottom: 20px; +} + +.task-table th, .task-table td { + padding: 15px; + text-align: left; + border-bottom: 1px solid #ddd; +} + +.task-table th { + background-color: #f8f9fa; + font-size: 1.2em; + font-weight: bold; +} + +.task-table tr:hover { + background-color: #f1f1f1; +} + +/* Additional Styles */ +a:link { + text-decoration: none; + color: inherit; +} + +div { + text-align: center; +} + +#first { + margin-top: 50px; +} diff --git a/N.Sunil-Easy/Task 3/task_manager.py b/N.Sunil-Easy/Task 3/task_manager.py new file mode 100644 index 0000000..4b7fbec --- /dev/null +++ b/N.Sunil-Easy/Task 3/task_manager.py @@ -0,0 +1,44 @@ +from flask import Flask, render_template, request, redirect, url_for +from flask_sqlalchemy import SQLAlchemy + +app = Flask(__name__) +app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///db.sqlite' +app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False +db = SQLAlchemy(app) + +class Todo(db.Model): + task_id = db.Column(db.Integer, primary_key=True) + name = db.Column(db.String(100)) + done = db.Column(db.Boolean) + +@app.route('/') +def home(): + todo_list = Todo.query.all() + return render_template('base.html', todo_list=todo_list) + +@app.route('/add', methods=['POST']) +def add(): + name = request.form.get("name") + new_task = Todo(name=name, done=False) + db.session.add(new_task) + db.session.commit() + return redirect(url_for("home")) + +@app.route('/update/') +def update(todo_id): + todo = Todo.query.get(todo_id) + todo.done = not todo.done + db.session.commit() + return redirect(url_for("home")) + +@app.route('/delete/') +def delete(todo_id): + todo = Todo.query.get(todo_id) + db.session.delete(todo) + db.session.commit() + return redirect(url_for("home")) + +if __name__ == '__main__': + with app.app_context(): + db.create_all() + app.run() diff --git a/N.Sunil-Easy/Task 3/templates/base.html b/N.Sunil-Easy/Task 3/templates/base.html new file mode 100644 index 0000000..bab6769 --- /dev/null +++ b/N.Sunil-Easy/Task 3/templates/base.html @@ -0,0 +1,47 @@ + + + + + Todo App + + + +
+

To Do List

+
+
+ + + +
+
+

+ + + + + + + + + + + + {% for todo in todo_list %} + + + + {% if todo.done == False %} + + {% else %} + + {% endif %} + + + + {% endfor %} + +
Task IDTask NameStatusUpdateDelete
{{ todo.task_id }}{{ todo.name }}UpdateDelete
+
+ + diff --git a/N.Sunil-Easy/audio_recorder.py b/N.Sunil-Easy/Task 4/audio_recorder.py similarity index 100% rename from N.Sunil-Easy/audio_recorder.py rename to N.Sunil-Easy/Task 4/audio_recorder.py From ac27cba0c37bb40bac8f7fe62c8ef7c9d62d25b9 Mon Sep 17 00:00:00 2001 From: sunil834 Date: Sun, 21 Jul 2024 23:01:18 +0530 Subject: [PATCH 7/8] Updated Code --- N.Sunil-Easy/{Task 3 => }/instance/db.sqlite | Bin 8192 -> 8192 bytes 1 file changed, 0 insertions(+), 0 deletions(-) rename N.Sunil-Easy/{Task 3 => }/instance/db.sqlite (96%) diff --git a/N.Sunil-Easy/Task 3/instance/db.sqlite b/N.Sunil-Easy/instance/db.sqlite similarity index 96% rename from N.Sunil-Easy/Task 3/instance/db.sqlite rename to N.Sunil-Easy/instance/db.sqlite index ab4507efcaa3c17eaeb6c4e08078ea165db754c3..ab7e1dbd1124c4c4ee1bbff4ea5ab907de48b24a 100644 GIT binary patch delta 28 kcmZp0XmFSy&B!=W#+i|EW5N=CCI*4cf&%CHCpKsU0C7|Y Date: Mon, 22 Jul 2024 00:15:21 +0530 Subject: [PATCH 8/8] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 81a0a3a..ee88ac1 100644 --- a/README.md +++ b/README.md @@ -87,7 +87,7 @@ Now let's dive into the tasks! 1. Web Scraping Tool with BeautifulSoup: - Develop a web scraping application using Python's BeautifulSoup library. Extract data from a website and present it in a structured format (e.g., CSV, JSON). -Basic Chatbot with NLTK: + 2. Basic Chatbot with NLTK: