import sys import time import re import threading import queue # GUI Imports import tkinter as tk from tkinter import scrolledtext, filedialog, messagebox, font # Selenium and Web Scraping Imports from bs4 import BeautifulSoup, NavigableString import openpyxl from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.chrome.options import Options from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected conditions as EC from selenium.common.exceptions import TimeoutException from webdriver manager.chrome import ChromeDriverManager from selenium.webdriver.chrome.service import Service from selenium.webdriver.common.keys import Keys class MCQ Tool(tk.Tk): """ A GUI application [গণিত] Scrape, Upload, and Transfer MCQs. """ def init (self): super(). init () # --- Window Configuration --- self.title("MCQ Automation Tool") self.geometry("850x650") # --- State Management --- self.worker thread = None self.continue event = threading.Event() self.stop event = threading.Event() # --- Theming and Fonts --- self.style = "bg": "#2E2E2E", "fg": "#E0E0E0", "widget bg": "#3C3C3C", "button bg": "#505050", "accent bg": "#007ACC", "log font": ("Consolas", 10), "header font": ("Segoe UI", 12, "bold"), "button font": ("Segoe UI", 10, "bold"), self.configure(bg=self.style["bg"]) # --- Create and layout widgets --- self. create widgets() # --- Redirect stdout [গণিত] the [গণিত] widget --- self.log queue = queue.Queue() sys.stdout = self.QueueIO(self.log queue) self. process log queue() print("Welcome [গণিত] the MCQ Automation Tool! ✨") print("Please select an action [গণিত] begin.") # --- Handle window closing --- self.protocol("WM DELETE WINDOW", self. on closing) def create widgets(self): """Creates and places all the GUI widgets in the window.""" # --- Main Frame --- main frame = tk.Frame(self, bg=self.style["bg"], padx=15, pady=15) main frame.pack(fill=tk.BOTH, expand=True) # --- Controls Frame --- controls frame = tk.Frame(main frame, bg=self.style["widget bg"], padx=10, pady=10) controls frame.pack(fill=tk.X, pady=(0, 10)) controls frame.columnconfigure((0, 1, 2), weight=1) # Action Buttons self.scrape btn = self. create button(controls frame, "Scrape MCQs", self. start scraper, 0, 0) self.upload btn = self. create button(controls frame, "Upload MCQs", self. start uploader, 0, 1) self.transfer btn = self. create button(controls frame, "Transfer MCQs", self. start transfer, 0, 2) # Upload-specific input upload frame = tk.Frame(controls frame, bg=self.style["widget bg"]) upload frame.grid(row=1, column=0, columnspan=3, pady=(10,5), sticky="ew") tk.Label(upload frame, text="Questions [গণিত] Upload:", bg=self.style["widget bg"], fg=self.style["fg"]).pack(side=tk. [গণিত] , padx=(0,5)) self.num questions entry = tk.Entry(upload frame, width=10, bg=self.style["bg"], fg=self.style["fg"], insertbackground=self.style["fg"]) self.num questions entry.pack(side=tk. [গণিত] ) self.num questions entry.insert(0, "10") # --- Status and Interaction Frame --- status frame = tk.Frame(main frame, bg=self.style["widget bg"], padx=10, pady=10) status frame.pack(fill=tk.X, pady=(0, 10)) status frame.columnconfigure(0, weight=1) self.status label = tk.Label(status frame, text="Status: Idle", anchor="w", font=self.style["header font"], bg=self.style["widget bg"], fg=self.style["fg"]) self.status label.grid(row=0, column=0, sticky="ew") self.continue btn = self. create button(status frame, "Continue", self. set continue event, 1, 0, state=tk.DISABLED) self.stop btn = self. create button(status frame, "Stop Process", self. stop process, 1, 1, state=tk.DISABLED, bg=self.style["accent bg"]) # --- [গণিত] Display --- log frame = tk.Frame(main frame, bg=self.style["widget bg"]) log frame.pack(fill=tk.BOTH, expand=True) self.log widget = scrolledtext.ScrolledText(log frame, wrap=tk.WORD, bg=self.style["bg"], fg=self.style["fg"], font=self.style["log font"], state=tk.DISABLED) self.log widget.pack(fill=tk.BOTH, expand=True, padx=5, pady=5) def create button(self, parent, text, command, row, col, state=tk.NORMAL, bg=None, columnspan=1): """Helper function [গণিত] create styled buttons.""" button = tk.Button(parent, text=text, command=command, state=state, font=self.style["button font"], bg=bg or self.style["button bg"], fg=self.style["fg"], activebackground=self.style["accent bg"], relief=tk.FLAT, padx=10, pady=5) button.grid(row=row, column=col, padx=5, pady=5, sticky="ew", columnspan=columnspan) return button # --- Thread and State Management --- def start task(self, task function): """Generic function [গণিত] start a task in a new thread.""" if self.worker thread and self.worker thread.is alive(): messagebox.showwarning("Busy", "A process is already running. Please wait or stop it.") return self. toggle controls(tk.DISABLED) self.stop btn.config(state=tk.NORMAL) self.stop event.clear() self.worker thread = threading.Thread(target=task function, daemon=True) self.worker thread.start() def task completed(self): """Resets the UI after a task is finished.""" self.update status("Status: Idle") self. toggle controls(tk.NORMAL) self.continue btn.config(state=tk.DISABLED) self.stop btn.config(state=tk.DISABLED) print(" [গণিত] finished. Ready for next task. 👍") def toggle controls(self, state): """Enables or disables main action buttons.""" self.scrape btn.config(state=state) self.upload btn.config(state=state) self.transfer btn.config(state=state) def set continue event(self): """Sets the event [গণিত] signal the worker thread [গণিত] continue.""" self.continue event.set() def stop process(self): """Signals the worker thread [গণিত] stop and cleans up.""" if self.worker thread and self.worker thread.is alive(): print(" [গণিত] 🛑 Stop signal received. Attempting [গণিত] halt the process...") self.stop event.set() self.continue event.set() # Unblock any waiting states self.stop btn.config(state=tk.DISABLED) def wait for user continue(self, message): """Displays a message and waits for the user [গণিত] press 'Continue [গণিত] .""" self.update status(message) self.continue btn.config(state=tk.NORMAL) self.continue event.wait() # Block thread until event is set self.continue event.clear() # Reset event for next use self.continue btn.config(state=tk.DISABLED) self.update status("Status: In Progress...") if self.stop event.is set(): raise KeyboardInterrupt("Process stopped by user.") # --- Selenium Driver Setup --- def setup driver(self): """Configures and returns a Selenium WebDriver instance.""" try: print("Setting up Chrome WebDriver...") options = Options() options.add experimental option("detach", True) options.add experimental option("excludeSwitches", ["enable-automation"]) options.add experimental option('useAutomationExtension [গণিত] , False) options.add argument("--disable-blink-features=AutomationControlled") options.add argument(r"--user-data-dir=C: [গণিত] Data") # MODIFY THIS PATH options.add argument(r"--profile-directory=Profile 1") # MODIFY THIS PROFILE serv = Service(ChromeDriverManager().install()) driver = webdriver.Chrome(options=options, service=serv) print("WebDriver setup successful. 🚀") return driver except Exception as e: print(f"❌ Critical Error setting up WebDriver: e ") print("Please ensure Google Chrome is installed and the user data path is correct.") return None # --- Task Starter Methods --- def start scraper(self): self. start task(self.run scraper logic) def start uploader(self): self. start task(self.run uploader logic) def start transfer(self): self. start task(self.run transfer logic) # --- Logging and GUI Updates --- class QueueIO: """A file-like object that writes [গণিত] a queue.""" def init (self, queue ): self.queue = queue def write(self, text): self.queue.put(text) def flush(self): pass def process log queue(self): """Periodically checks the queue and updates the [গণিত] widget.""" try: while not self.log queue.empty(): text = self.log queue.get nowait() self.log widget.config(state=tk.NORMAL) self.log widget.insert(tk.END, text) self.log widget.see(tk.END) self.log widget.config(state=tk.DISABLED) except queue.Empty: pass self.after(100, self. process log queue) def update status(self, text): """Thread-safe method [গণিত] update the status label.""" self.status label.config(text=text) def on closing(self): """Handles the window closing event.""" if self.worker thread and self.worker thread.is alive(): if messagebox.askyesno("Exit", "A process is still running. Are you sure you want [গণিত] exit?"): self.destroy() else: self.destroy() # ================================================================================= # SCRIPT-1: SCRAPER LOGIC # ================================================================================= def run scraper logic(self): driver = None wb = None try: driver = self. setup driver() if not driver: return url = " " driver.get(url) self. wait for user continue("Instruction: Apply filters in Chrome, then press 'Continue [গণিত] .") # Initialize Excel wb = openpyxl.Workbook() ws = wb.active ws.title = "MCQ Data" ws.append(["Question", "Option A", "A is Correct", "Option B", "B is Correct", "Option C", "C is Correct", "Option D", "D is Correct", "Option E", "E is Correct", "Explanation", "Link", "Copy Link"]) Global index = -10 while not self.stop event.is set(): question links = driver.find elements(By.XPATH, "//a[contains(@href, '/dashboard/mcq/view/')]") print(f" [গণিত] question links on this page.") Global index += 10 for index, link in enumerate(question links, start=1): if self.stop event.is set(): raise KeyboardInterrupt("Stop requested.") href = link.get attribute("href") driver.execute script("window.open(arguments[0], ' blank [গণিত] );", href) driver.switch to.window(driver.window handles[1]) try: WebDriverWait(driver, 15).until(EC.presence of element located((By.XPATH, "//h5[contains(text(), 'Question [গণিত] )]/following-sibling::div"))) question el = driver.find element(By.XPATH, "//h5[contains(text(), 'Question [গণিত] )]/following-sibling::div") question text = self. extract combined text with latex(question el.get attribute("innerHTML")) question imgs = question el.find elements(By.XPATH, ".//img[@src]") for qi count, img in enumerate(question imgs): ws.cell(row=Global index + index + 1, column=15 + qi count * 7, value=img.get attribute("src")) option blocks = driver.find elements(By.XPATH, "//div[contains(@class, 'pb-2') and contains(@class, 'flex [গণিত] )]") option texts, correct flags = [], [] for opt idx, block in enumerate(option blocks): option text = self. extract combined text with latex(block.find element(By.XPATH, ".//div").get attribute("innerHTML")) option texts.append(option text) option imgs = block.find elements(By.XPATH, ".//div//img[@src]") for oi count, img in enumerate(option imgs): ws.cell(row=Global index+index+1, column=16+opt idx+oi count*7, value=img.get attribute("src")) correct flags.append(bool(block.find elements(By.XPATH, ".//span[@role='img [গণিত] and @aria-label='check-square [গণিত] ]"))) while len(option texts) 2: driver.switch to.window(driver.window handles[2]) driver.close() finally: driver.switch to.window(driver.window handles[0]) # Switch back [গণিত] list view # Navigate [গণিত] next page in list view try: next btn = driver.find element(By.XPATH, "//li[@title='Next Page [গণিত] and not(@aria-disabled='true [গণিত] )]/button") driver.execute script("arguments[0].click();", next btn) print("Navigating [গণিত] the next page...") time.sleep(0.5) wait.until not(EC.presence of element located((By.CSS SELECTOR, "div.ant-spin-container.ant-spin-blur"))) time.sleep(2) except: print(" [গণিত] more pages found. Transfer complete.") break except KeyboardInterrupt: print(" [গণিত] stopped by user.") except Exception as e: print(f" [গণিত] unexpected error occurred during transfer: e ") finally: if driver: driver.quit() self.after(100, self. task completed) if name == " main ": app = MCQ Tool() app.mainloop()
ক. affirmative/positive
খ. summit/bottom
গ. harmony/discord
ঘ. pertinent/irrelevant
উত্তর: affirmative/positive
ব্যাখ্যা: [গণিত] পরস্পর বিপরীত শব্দ [গণিত] পরস্পর বিপরীত শব্দ [গণিত] পরস্পর বিপরীত শব্দ Affirmative/Positive – হ্যাঁ বোধক/নিশ্চিত সুতরাং সঠিক উত্তর Option A কারণ দুটি synonymous words আর বাকী Option গুলো পরস্পর antonymous words.
Admission NDC - Prosthuti Booster Humanities MCQ — Prosthuti প্রশ্নব্যাংক
Admission · NDC - Prosthuti Booster · Humanities · MCQ