<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: writing</title>
    <description>The latest articles tagged 'writing' on DEV Community.</description>
    <link>https://dev.to/t/writing</link>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tag/writing"/>
    <language>en</language>
    <item>
      <title>Best Freelance Writing Platforms 2026</title>
      <dc:creator>Sylvia A Sinatra</dc:creator>
      <pubDate>Sat, 22 Aug 2026 16:05:13 +0000</pubDate>
      <link>https://dev.to/sinatra182/best-freelance-writing-platforms-2026-6nh</link>
      <guid>https://dev.to/sinatra182/best-freelance-writing-platforms-2026-6nh</guid>
      <description>&lt;h1&gt;
  
  
  Best Freelance Writing Platforms 2026
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In 2026, earning money online is more accessible than ever. This guide covers&lt;br&gt;
real methods that pay — no fluff.&lt;/p&gt;

&lt;h2&gt;
  
  
  Methods That Work
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Microtasks&lt;/strong&gt; — small tasks on SproutGigs, earn crypto or PayPal.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Airdrop Farming&lt;/strong&gt; — join testnets, claim tokens pre-listing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content Writing&lt;/strong&gt; — publish on revenue-share platforms.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Freelance&lt;/strong&gt; — sell skills on Upwork, Fiverr.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Staking &amp;amp; Nodes&lt;/strong&gt; — passive income from crypto.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;Sign up, verify email, finish onboarding, then execute consistently.&lt;br&gt;
Payouts stack and withdraw to USDT wallets.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Consistency beats intensity. Start today, compound daily.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Tags: freelance, writing, content&lt;/em&gt;&lt;/p&gt;

</description>
      <category>freelance</category>
      <category>writing</category>
      <category>content</category>
    </item>
    <item>
      <title>How to Build a $1500/Month Technical Writing Agency</title>
      <dc:creator>qing</dc:creator>
      <pubDate>Sat, 22 Aug 2026 16:00:05 +0000</pubDate>
      <link>https://dev.to/qingluan/how-to-build-a-1500month-technical-writing-agency-2bko</link>
      <guid>https://dev.to/qingluan/how-to-build-a-1500month-technical-writing-agency-2bko</guid>
      <description>&lt;h1&gt;
  
  
  How to Build a $1500/Month Technical Writing Agency
&lt;/h1&gt;

&lt;p&gt;tags: writing, money, freelance, startup&lt;/p&gt;




&lt;p&gt;tags: writing, money, freelance, startup&lt;/p&gt;




&lt;p&gt;tags: writing, money, freelance, startup&lt;/p&gt;




&lt;p&gt;tags: ai, python, writing, money&lt;/p&gt;




&lt;p&gt;tags: ai, python, writing, money&lt;/p&gt;




&lt;h1&gt;
  
  
  How to Build a Profitable AI Writing Assistant
&lt;/h1&gt;

&lt;p&gt;Imagine finishing a 1,000-word blog post in three minutes, editing it to sound like a seasoned human expert, and selling it for $50 before lunch. That’s not a fantasy; it’s the daily reality for developers who’ve turned simple AI scripts into revenue-generating products. The barrier to entry has collapsed, but the opportunity to build something &lt;em&gt;profitable&lt;/em&gt; hasn’t. Most people are just playing with chatbots; you’re here to build a tool that solves a real pain point and gets paid for it.&lt;/p&gt;

&lt;p&gt;The secret isn’t just using a better model—it’s about &lt;strong&gt;productizing a specific workflow&lt;/strong&gt; for a &lt;strong&gt;micro-niche&lt;/strong&gt;. Let’s build the core engine of an AI writing assistant today, then map out exactly how to monetize it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Architecture: Keep It Simple, Scale Later
&lt;/h2&gt;

&lt;p&gt;Don’t try to build a ChatGPT clone. You need a focused tool that does three things exceptionally well: &lt;strong&gt;rewrite&lt;/strong&gt;, &lt;strong&gt;summarize&lt;/strong&gt;, and &lt;strong&gt;change tone&lt;/strong&gt;. These are the highest-value tasks for freelancers, marketers, and content creators.&lt;/p&gt;

&lt;p&gt;Your app needs three components:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;A lightweight UI&lt;/strong&gt;: A text box and task buttons (Rewrite, Summarize, Tone Shift).&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;A server route&lt;/strong&gt;: Handles the API key securely and manages the request.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;System prompts&lt;/strong&gt;: A dedicated prompt for each task that defines the persona and constraints.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When a user clicks a button, your server selects the matching system prompt, sends the user’s text to the LLM API, and streams the result back. This architecture is robust enough for a MVP (Minimum Viable Product) and cheap to host.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building the Core: A Working Python Example
&lt;/h2&gt;

&lt;p&gt;Let’s write the server logic right now. You can run this locally with &lt;code&gt;streamlit&lt;/code&gt; for the UI or deploy it as a simple API. We’ll use the &lt;code&gt;openai&lt;/code&gt; library (which works with most providers like OpenAI, Anthropic, or local LLMs via compatible endpoints).&lt;/p&gt;

&lt;p&gt;Here’s a complete, runnable script that implements the three core tasks with &lt;strong&gt;role-based prompting&lt;/strong&gt; and &lt;strong&gt;anti-pattern constraints&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;

&lt;span class="c1"&gt;# Initialize the client (set your API key in env: OPENAI_API_KEY)
&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;OPENAI_API_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;# Define system prompts for specific tasks
&lt;/span&gt;&lt;span class="n"&gt;SYSTEM_PROMPTS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rewrite&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
    You are a senior copy editor with 15 years of experience.
    Task: Rewrite the user&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s text to be clearer, more engaging, and concise.
    Constraints:
    - Avoid passive voice, clichés, and filler phrases.
    - Maintain the original meaning but improve flow.
    - Output ONLY the rewritten text, no explanations.
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;summarize&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
    You are a technical journalist who excels at distilling complex ideas.
    Task: Summarize the user&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s text into 3 key bullet points.
    Constraints:
    - Use active voice and specific vocabulary.
    - Keep each bullet under 15 words.
    - Output ONLY the bullets, no intro/outro.
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tone_shift&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
    You are a brand voice specialist.
    Task: Rewrite the user&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s text to sound &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Professional yet Friendly&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; (like a helpful SaaS expert).
    Constraints:
    - Avoid marketing jargon and overly formal language.
    - Be direct and accessible for non-technical readers.
    - Output ONLY the rewritten text.
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;generate_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user_text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;system_prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SYSTEM_PROMPTS&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gpt-4o-mini&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# Fast and cheap for MVP
&lt;/span&gt;        &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;system&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;system_prompt&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;user_text&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.7&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;

&lt;span class="c1"&gt;# Example usage (replace with your actual UI logic)
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The product is really good and people like it a lot because it works well.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Rewritten:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;generate_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rewrite&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Summarized:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;generate_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;summarize&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Tone Shift:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;generate_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tone_shift&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code is production-ready for a prototype. It uses &lt;strong&gt;specific constraints&lt;/strong&gt; to prevent the AI from hallucinating or adding fluff, which is critical for maintaining quality.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Monetization Strategy: Pick a Micro-Niche
&lt;/h2&gt;

&lt;p&gt;You can’t just sell “AI writing.” You need to sell “AI writing for &lt;strong&gt;X&lt;/strong&gt;.” Profitability comes from specificity.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The Service Arbitrage Model
&lt;/h3&gt;

&lt;p&gt;Start by offering a service on Fiverr or Upwork. Pick a niche like &lt;strong&gt;“blog posts for SaaS companies”&lt;/strong&gt; or &lt;strong&gt;“product descriptions for Shopify stores.”&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Action Step&lt;/strong&gt;: Create 3 polished samples using your new script. List your service at $15–$25 per piece.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Why it works&lt;/strong&gt;: You apply the AI to do 80% of the work, then manually edit for voice. You can deliver 5x faster than competitors, undercutting them on price while keeping your margins high [1].&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. The Digital Product Model
&lt;/h3&gt;

&lt;p&gt;Build a pack of 50 specialized prompts for a specific use case, like &lt;strong&gt;“ChatGPT prompts for Etsy product descriptions.”&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Action Step&lt;/strong&gt;: Test every prompt yourself. Only include what produces good output. List it on Gumroad (where you keep 90%+ of revenue) and promote it in relevant Reddit communities [1].&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Why it works&lt;/strong&gt;: People pay for convenience. They don’t want to figure out the prompt; they want the result.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. The Agency Scaling Model
&lt;/h3&gt;

&lt;p&gt;If you’re already a freelancer, use your assistant to scale into an agency.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Action Step&lt;/strong&gt;: Productize your services into 2–3 clear packages (Starter, Growth, Premium). Use your AI tool to generate structured outlines and first drafts instantly, then hand off the editing to contractors [3].&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Why it works&lt;/strong&gt;: Your profit grows as your efficiency improves. You measure time saved on drafting vs. editing and adjust pricing accordingly [3].&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Quality Control: The Human-in-the-Loop
&lt;/h2&gt;

&lt;p&gt;The biggest risk to profitability is bad output. Your assistant must be tuned to avoid the “AI smell.”&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Be Specific on Format&lt;/strong&gt;: Tell the model exactly what structure you expect (headings, bullets, paragraphs) [4].&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Provide Style Examples&lt;/strong&gt;: Include a sample paragraph in the desired style as a reference [4].&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Set Constraints&lt;/strong&gt;: Specify word count ranges, reading level, and vocabulary preferences [4].&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;The Fact-Check Pass&lt;/strong&gt;: Never ship raw AI output. Always run a factual check and edit for voice and accuracy [3].&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A repeatable workflow for your business is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Collect a concise brief from the client.&lt;/li&gt;
&lt;li&gt; Use AI to generate a structured outline.&lt;/li&gt;
&lt;li&gt; Ask AI to produce a first draft based on that outline.&lt;/li&gt;
&lt;li&gt; Have a human editor perform a single focused edit pass [3].&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Launching Today: Your 24-Hour Plan
&lt;/h2&gt;

&lt;p&gt;You don’t need months to build this. Here is your roadmap for the next 24 hours:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Hour 1–2&lt;/strong&gt;: Run the Python code above. Customize the &lt;code&gt;SYSTEM_PROMPTS&lt;/code&gt; for your chosen niche (e.g., change the tone to “Witty and Bold” for a fashion brand).&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Hour 3–4&lt;/strong&gt;: Create 3 high-quality samples using your script. Polish them manually until they don’t read like AI.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Hour 5–6&lt;/strong&gt;: Open a Fiverr/Upwork account or a Gumroad page. List your service/product.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Hour 7+&lt;/strong&gt;: Send 20 cold messages on LinkedIn or apply to 5 jobs per day. The goal is to get your first client or sale, not to perfect the code [1].&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion: Build, Iterate, Profit
&lt;/h2&gt;

&lt;p&gt;The future of AI writing isn’t about replacing humans; it’s about &lt;strong&gt;supercharging them&lt;/strong&gt;. By building a focused assistant that handles the heavy lifting of drafting and rewriting, you free up your time for the high-value work of strategy and editing.&lt;/p&gt;

&lt;p&gt;Don’t wait for a perfect product. The code above is your engine. The niche you pick is your fuel. The market is ready to pay for speed and quality.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your call to action&lt;/strong&gt;: Copy the Python script, run it with your own API key, and generate your first sample &lt;em&gt;right now&lt;/em&gt;. Then, list it on a platform and start selling. The only thing between you and a profitable AI business is the first line of code you write today.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;If you found this helpful, consider &lt;a href="https://ko-fi.com/qingluan" rel="noopener noreferrer"&gt;buying me a coffee ☕&lt;/a&gt; — it keeps these articles coming!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Also check out my AI tools collection: &lt;a href="https://ai.xn--4ds5cia.xn--rhqv96g/" rel="noopener noreferrer"&gt;AI 次元世界&lt;/a&gt; — free AI tools for developers.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>writing</category>
      <category>money</category>
      <category>freelance</category>
      <category>startup</category>
    </item>
    <item>
      <title>Best Freelance Writing Platforms 2026</title>
      <dc:creator>Sylvia A Sinatra</dc:creator>
      <pubDate>Sat, 22 Aug 2026 14:37:06 +0000</pubDate>
      <link>https://dev.to/sinatra182/best-freelance-writing-platforms-2026-119f</link>
      <guid>https://dev.to/sinatra182/best-freelance-writing-platforms-2026-119f</guid>
      <description>&lt;h1&gt;
  
  
  Best Freelance Writing Platforms 2026
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In 2026, earning money online is more accessible than ever. This guide covers&lt;br&gt;
real methods that pay — no fluff.&lt;/p&gt;

&lt;h2&gt;
  
  
  Methods That Work
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Microtasks&lt;/strong&gt; — small tasks on SproutGigs, earn crypto or PayPal.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Airdrop Farming&lt;/strong&gt; — join testnets, claim tokens pre-listing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content Writing&lt;/strong&gt; — publish on revenue-share platforms.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Freelance&lt;/strong&gt; — sell skills on Upwork, Fiverr.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Staking &amp;amp; Nodes&lt;/strong&gt; — passive income from crypto.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;Sign up, verify email, finish onboarding, then execute consistently.&lt;br&gt;
Payouts stack and withdraw to USDT wallets.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Consistency beats intensity. Start today, compound daily.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Tags: freelance, writing, content&lt;/em&gt;&lt;/p&gt;

</description>
      <category>freelance</category>
      <category>writing</category>
      <category>content</category>
    </item>
    <item>
      <title>Do journals check papers for AI writing?</title>
      <dc:creator>Nylah Reynard</dc:creator>
      <pubDate>Sat, 22 Aug 2026 13:33:28 +0000</pubDate>
      <link>https://dev.to/yotta-fish/do-journals-check-papers-for-ai-writing-4bkn</link>
      <guid>https://dev.to/yotta-fish/do-journals-check-papers-for-ai-writing-4bkn</guid>
      <description>&lt;p&gt;"Do journals check papers for AI writing?" reads like a yes/no question. It is really a question about feature flags, licensing and per-request eligibility, which is why nobody can answer it for your submission without knowing three separate things.&lt;/p&gt;

&lt;p&gt;One publisher says in writing what its routine screen is for, and the object it names is duplicated text rather than an AI score. The AI writing indicator is sold as a paid add-on on top of that, and even where it is licensed and switched on, an individual submission still has to clear file-type, language and word-count gates before a report exists at all. Below: the quotes, the gates, and where to look up the rule that actually governs your own submission.&lt;/p&gt;

&lt;h2&gt;
  
  
  The short answer
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Not necessarily. Wiley describes routine screening for duplicated text, which is a similarity check rather than an AI writing score. iThenticate sells AI writing detection as a paid add-on, so institutional licensing and enablement are one gate. A particular submission then has to meet Turnitin's file-type, language and qualifying-word requirements, so a missing AI section does not identify one cause by itself. In the seven named publisher and ethics-body policy pages we reviewed on 18 August 2026, none supplied a universal journal AI percentage to aim at. Those documents focused instead on authorship, responsibility and disclosure.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So "is there an AI rate limit for journals" is a question built on a step that may not exist for your submission. The answerable questions are narrower: what is actually run, where a number would come from if there is one, and what you are obliged to declare regardless.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is actually run at submission
&lt;/h2&gt;

&lt;p&gt;Publishers do describe screening incoming manuscripts, and at least one of them writes out what the screen is for in a single sentence. From Wiley's publishing ethics guidelines, under the heading on plagiarism:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Wiley routinely screens submitted manuscripts for duplicated text using tools such as Crossref Similarity Check. If significant and unexplained overlap is identified, we will follow COPE guidelines on handling plagiarism in a submitted manuscript or published article to resolve the issue."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Read the object of that sentence. Duplicated text. Crossref's page for the service then describes iThenticate as providing a Similarity Report "containing a Similarity Score and a highlighted set of matches to similar text". That description gives you the object being measured without asking a word-count search to stand in for the page.&lt;/p&gt;

&lt;p&gt;That is a different measurement from an AI writing score, and it is different in kind rather than in degree. Who runs it, what your sentences are compared against, and why your own earlier paper can turn up as a match are all in who runs the similarity check on your manuscript, and what it compares against. One thing worth carrying into the next section: whether your manuscript goes through this particular check is a fact about your publisher, not about your field.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where an AI percentage would come from
&lt;/h2&gt;

&lt;p&gt;Same vendor, different purchase. Turnitin's iThenticate product page answers this in its own FAQ:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"iThenticate customers can access AI writing detection as a paid add-on. Once licensed and enabled, Turnitin's AI writing indicator, which is integrated within the Similarity Report, shows an overall percentage of the document that AI writing tools such as ChatGPT may have generated."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The feature list on the same page draws the same boundary: the Similarity Report appears under "Core features", while "AI writing detection" appears under "Add-ons".&lt;/p&gt;

&lt;p&gt;Licensing and enablement are only the first gate. Turnitin's own report guide shows an "AI writing detection is unavailable for this submission" state whose possible reasons include an unsupported file type, an unsupported language, or qualifying text below 300 words or above 30,000 words. A separate state says detection was disabled at the time of submission. So "the journal checked my paper" can describe different events, and if someone quotes you a figure it is fair to ask which report it sat in and whether the file was eligible for that report.&lt;/p&gt;

&lt;p&gt;A missing AI section therefore tells you only that this report does not display an AI result. It does not, by itself, distinguish licensing from submission eligibility or processing state. Ask the report owner which condition applied. The documented language boundary is covered separately in can Turnitin detect AI in non-English submissions?.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the policy review can and cannot show
&lt;/h2&gt;

&lt;p&gt;On 18 August 2026 we reviewed seven specific policy pages from six organisations. Naming them matters because this is a bounded document review, not a claim about every publisher or every journal.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Organisation&lt;/th&gt;
&lt;th&gt;Policy page reviewed&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Nature Portfolio&lt;/td&gt;
&lt;td&gt;Artificial Intelligence (AI)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Wiley&lt;/td&gt;
&lt;td&gt;Best Practice Guidelines on Publishing Ethics&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Taylor &amp;amp; Francis&lt;/td&gt;
&lt;td&gt;AI Policy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Taylor &amp;amp; Francis&lt;/td&gt;
&lt;td&gt;Defining authorship in your research paper&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SAGE&lt;/td&gt;
&lt;td&gt;Artificial intelligence policy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ICMJE&lt;/td&gt;
&lt;td&gt;Defining the Role of Authors and Contributors&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;COPE&lt;/td&gt;
&lt;td&gt;Authorship and AI tools&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;None of those seven documents supplied a universal journal AI percentage for authors to aim at. They addressed questions such as who can be an author, who remains responsible for the manuscript, and when AI use should be disclosed. That finding is limited to those named pages as read on that date. It does not prove that no publisher or journal has an additional rule, and it says nothing about whether an institution licensed a detector.&lt;/p&gt;

&lt;p&gt;Elsevier is not part of that seven-page finding because its policy page did not load reliably in our browser. We use one directly recoverable disclosure sentence from it below and make no absence claim from the failed retrieval.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The seven-page review gives no universal percentage to target. It gives a map of publisher-level disclosure questions, which still has to be narrowed to the journal and submission system handling your paper.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What the policies do contain
&lt;/h2&gt;

&lt;p&gt;The recurring issue in the reviewed policies is telling people what was done, although the exact boundary varies. Elsevier's journals policy puts one version of that boundary in two sentences:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Basic checks of grammar, spelling and punctuation do not need a declaration statement. However, when an AI tool makes substantive changes to sentence structure or organization of a part of the text, this should be disclosed."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That line is worth sitting with if any part of your workflow reshapes sentences, because it is drawn around what the tool did to the text rather than around what the tool is called.&lt;/p&gt;

&lt;p&gt;COPE's position says AI cannot be an author because it cannot take responsibility, declare conflicts or manage licences. It then says authors who used AI in writing, producing images, or collecting and analysing data "must be transparent in disclosing in the Materials and Methods (or similar section) of the paper how the AI tool was used and which tool was used". That is guidance about responsibility and transparency, not a journal-specific score to target.&lt;/p&gt;

&lt;p&gt;Where the statement goes, and what each publisher exempts, is the part that varies and the part people get wrong at submission. We put six of them side by side in publisher AI disclosure policies, compared.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to look for your own answer
&lt;/h2&gt;

&lt;p&gt;Everything above is publisher-level, which is the floor rather than the answer. Your answer lives in narrower documents, and they are worth reading in this order.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Where&lt;/th&gt;
&lt;th&gt;What it can settle&lt;/th&gt;
&lt;th&gt;How to pin it down&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;The journal's instructions for authors&lt;/td&gt;
&lt;td&gt;Whether this specific title adds anything to the publisher default, and what the declaration has to look like&lt;/td&gt;
&lt;td&gt;Search the page for "artificial intelligence" and for "declaration". Save the version and the date you read it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The submission portal itself&lt;/td&gt;
&lt;td&gt;What you will be asked to tick or type at upload&lt;/td&gt;
&lt;td&gt;Open it before the deadline, not on it. The portal question is often narrower than the author guide, and the two are not always in sync&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The publisher's AI policy page&lt;/td&gt;
&lt;td&gt;The floor everything else sits on, and the exemption wording&lt;/td&gt;
&lt;td&gt;Read the exemption, not a summary of it. "Grammar and spelling" and "copy editing" are not the same size&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The editorial office&lt;/td&gt;
&lt;td&gt;Anything the pages leave open&lt;/td&gt;
&lt;td&gt;Ask something specific, like whether the journal runs an AI writing report on submissions. General questions get general answers&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If the answer comes back as "we do not have a number", that is an answer and not a brush-off. It tells you the trigger is not a threshold you can aim at, so the useful preparation is a record of how the manuscript was written, not a target figure.&lt;/p&gt;

&lt;h2&gt;
  
  
  If a rewriting step is part of your workflow
&lt;/h2&gt;

&lt;p&gt;Then keep the two questions apart, because they answer to different documents. A rewrite operates on wording. A disclosure rule asks what happened while the manuscript was being written, and nothing you do to the wording later travels back to that. We wrote our own position on it in does running your document through a rewriting tool change what you have to declare?, and Elsevier's "substantive changes to sentence structure or organization" line above is the version that matters at submission.&lt;/p&gt;

&lt;p&gt;Where a report already exists and it marks particular paragraphs, that is the narrow situation HumanPen is built for. You upload the manuscript and the report together, it works only on the marked passages, and the rest of the file comes back as it went in.&lt;/p&gt;

&lt;p&gt;What we are not going to give you is a target figure. None of the sources above sets one, inventing one is not ours to do, and a rewriting vendor announcing what counts as acceptable would be exactly the wrong party to ask.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Does every journal run an AI check on submissions?&lt;/strong&gt; Do not assume it in either direction. Wiley publicly describes routine screening for duplicated text, while iThenticate sells AI writing detection as an add-on. Even where it is licensed and enabled, a submission still has to meet the report's file, language and qualifying-word requirements. Ask the journal or report owner which checks apply to this submission.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is there an AI percentage limit for journal submissions?&lt;/strong&gt; None of the seven named policy pages in our review supplied a universal limit. That does not rule out a title-specific instruction, so ask which document a quoted figure came from. The most-quoted number in this area is a display rule rather than a journal limit, which we unpacked in is 20% AI too high? why there is no absolute threshold.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My similarity report has no AI section. Does that mean the paper was not checked for AI?&lt;/strong&gt; It means only that this report does not display an AI result. Possible reasons include licensing or enablement, an unsupported file type or language, qualifying text outside the documented word range, or the feature being disabled at submission. Ask the report owner which state applied rather than diagnosing it from the missing section alone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do I have to declare AI use if I rewrote everything myself afterwards?&lt;/strong&gt; Read the exemption wording rather than reasoning from how much you changed. Elsevier's page exempts basic grammar, spelling and punctuation checks and says substantive changes to sentence structure or organisation should be disclosed. Other publishers word the same boundary differently, which is why the comparison page exists.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;An editor asked about AI use in my paper. Is that a detection result?&lt;/strong&gt; Not necessarily, and it is worth establishing before you answer. Ask what prompted the question and which report, if any, it came from. A question can come from a reviewer's impression, from a similarity finding, or from a portal declaration that did not match the manuscript, and those need different replies. A checklist for the pass before submission is in final manuscript check: AI disclosure, word count, citations and DOCX integrity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Working from a report that flags particular paragraphs?
&lt;/h2&gt;

&lt;p&gt;Upload the manuscript and the report together. Only the flagged passages are rewritten, and the rest of the file is left exactly as it was.&lt;/p&gt;




&lt;p&gt;Originally published at &lt;a href="https://humanpen.net/blog/do-journals-check-for-ai-writing?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=d67" rel="noopener noreferrer"&gt;https://humanpen.net/blog/do-journals-check-for-ai-writing?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=d67&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>writing</category>
      <category>documentation</category>
      <category>career</category>
    </item>
    <item>
      <title>Why Turnitin says your work is 100% AI</title>
      <dc:creator>Nylah Reynard</dc:creator>
      <pubDate>Sat, 22 Aug 2026 13:32:14 +0000</pubDate>
      <link>https://dev.to/yotta-fish/why-turnitin-says-your-work-is-100-ai-665</link>
      <guid>https://dev.to/yotta-fish/why-turnitin-says-your-work-is-100-ai-665</guid>
      <description>&lt;p&gt;A score of 100 is not a more confident 60. In the vendor's own description of how the number is computed, the extremes are where the aggregation had the least to work with.&lt;/p&gt;

&lt;p&gt;The mechanism is ordinary if you have ever built anything that windows a document and pools per-window scores: sentences get grouped into overlapping segments, each segment is classified, each sentence inherits the scores of every segment it belongs to, and those are pooled and aggregated. Take the overlap away, which is what happens in a short document, and the output collapses toward the ends. The vendor documents that behaviour explicitly, and it is the first of three things worth ruling out before treating a 100 as a statement about the writing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start here, before the explanation
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Three situations produce a 100 much more often than "every sentence you wrote reads like a machine wrote it", and you can rule them in or out in about ten minutes. Check which number you are holding: Turnitin says the AI writing indicator is not visible to students, so a percentage you found yourself, inside your own view, is the similarity score rather than the AI one. Check how much prose the file contains: Turnitin says that in documents of only a few hundred words the prediction is "mostly 'all or nothing'", because it is predicting on a single segment with no opportunity to overlap. Check what the 100 is 100% of: the percentage is computed over qualifying text, and Turnitin says that figure "is not necessarily the percentage of the entire submission". Only when all three are ruled out does it make sense to ask what the model saw in the writing itself.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The three call for completely different responses, which is why the order matters more than the explanation. This page is about how an extreme number gets produced. It is not a script for a misconduct meeting, and nothing here predicts what a future report will say.&lt;/p&gt;

&lt;h2&gt;
  
  
  First, check which 100 you are holding
&lt;/h2&gt;

&lt;p&gt;Turnitin is explicit about who can see the AI number. Its guidance says "only instructors and administrators are able to see the indicator", and separately that "The AI writing detection indicator and report are not visible to students." The sentence immediately after the second one matters just as much: "However, with the PDF download feature, instructors can download and share the AI report with students." So both routes exist. A PDF someone sent you can genuinely be the AI report. A percentage you clicked into yourself, in your own submission view, is not the AI indicator.&lt;/p&gt;

&lt;p&gt;That leaves the other number, and 100 is a much more ordinary value there. A similarity score of 100% has a documented and completely innocent route: your own earlier drafts, stored by a different assignment, matching your final version almost word for word. We traced how that happens, and when it does not, in will my earlier draft match my resubmission. The two reports are separate analyses that can disagree in all four directions, which is the subject of AI report vs similarity report.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A 100 on the similarity side and a 100 on the AI side are different findings with different causes and different responses. Spending an evening on the wrong one is the most common way this goes badly.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Short documents are scored all or nothing
&lt;/h2&gt;

&lt;p&gt;Turnitin's published description of the calculation has three moves in it: sentences are pulled out and grouped into overlapping segments, each segment gets a probability between 0 and 1, and every qualifying sentence inherits the score of each segment it sits in. Because the segments overlap, a sentence near a boundary carries more than one score, which are then pooled. Those pooled sentence scores are what get aggregated into the document figure. The averaging is the whole reason a document can come back at 43 rather than at one of the ends.&lt;/p&gt;

&lt;p&gt;Now take that away. Turnitin's FAQ says what happens when there is nothing to average across:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"In shorter documents where there are only a few hundred words, the prediction will be mostly 'all or nothing' because we're predicting on a single segment without the opportunity to overlap. This means that some text that is a mix of AI-generated and original content could be flagged as entirely AI-generated."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Read that as a statement about resolution rather than about accuracy. In a long document, a 100 would mean a large number of separate predictions all landed on the same side. In a document of a few hundred words it can mean one prediction, which the interface then renders as a percentage. The two are displayed identically and are not the same kind of evidence, and the second sentence of that quote says outright that mixed content is what gets swept up.&lt;/p&gt;

&lt;p&gt;There is a floor underneath this. A submission needs at least 300 words of prose in a long-form format before an AI report is generated at all. So the shortest file that can receive a number is also the one whose number rests on the fewest independent observations, and the band just above the floor is where those two facts overlap. A 900-word reflective piece, a short problem set write-up, a conference abstract padded to length: all of them sit in the zone Turnitin describes. What happens at the other end of the range, where a thesis exceeds what one report covers, we went through in can Turnitin check a whole thesis.&lt;/p&gt;

&lt;h2&gt;
  
  
  100% of what, exactly
&lt;/h2&gt;

&lt;p&gt;The percentage is not calculated over your document. It is calculated over what Turnitin calls qualifying text, and the definition is narrow: "This qualifying text includes only prose sentences, meaning that we only analyze blocks of text that are written in standard grammatical sentences and do not include other types of writing such as lists, bullet points (short non-sentence structures), or other non-sentence structures." The sentence that follows is the one to hold on to: "This percentage is not necessarily the percentage of the entire submission."&lt;/p&gt;

&lt;p&gt;Some exclusions are stated separately. Turnitin's release notes record that a bug highlighting AI writing inside bibliographies was fixed and that "Bibliographies are now excluded when processing the AI writing report", and elsewhere that "We are now able to process long-form prose text in tables." Both entries end the same way, with an instruction not to assume the change applies to what you already submitted: resubmit to reprocess. So a reference list is outside the calculation, and paragraphs sitting inside a table are inside it, which is not the intuition most people have about either.&lt;/p&gt;

&lt;p&gt;Put a real file through that. A 5,000-word lab report with a methods table, three bulleted protocol lists, an appendix and 60 references might contain 2,000 words that qualify. A 100 on that report is a statement about those 2,000 words. It is not a statement about the other 3,000, which were never assessed and cannot be defended or attacked on the basis of the number.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is also why a 100 can coexist with pages that carry no highlighting at all. Turnitin says a document containing several different writing types "would result in a disparity between the percentage and the highlights". At the top of the range that disparity looks like a contradiction, and it is expected behaviour.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Counting highlighted lines and comparing them against the percentage will not resolve it, because the two are computed over different things. How to read a Turnitin AI writing report works through the rest of the report states for the same reason.&lt;/p&gt;

&lt;h2&gt;
  
  
  When the document is long and still comes back at the top
&lt;/h2&gt;

&lt;p&gt;If the file is 8,000 words of continuous prose, the single-segment explanation is gone. Many separate predictions did land on the same side, and the question becomes what would make an entire document look the same way to the model all the way through. Turnitin publishes a partial answer, in the form of the properties it says show up in its own false positives:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Sometimes false positives (incorrectly flagging human-written text as AI-generated), can include content without a lot of structural variation, text that literally repeats itself, or text that has been paraphrased without developing new ideas. If our indicator shows a higher amount of AI writing in such text, we advise you to take that into consideration when looking at the percentage indicated."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Those three properties are all properties of a whole document rather than of a sentence. That is our reading and not something Turnitin claims, but it is the part that fits the shape of the question: a paper written to a mandated section order, in a discipline with a fixed way of phrasing a methods paragraph, restating its own aims in the abstract and again in the introduction and again in the discussion, has roughly the same character in every segment. There is no passage that differs enough from its neighbours to pull the aggregate down. Uniformity is not a writing fault, and in several genres it is the requirement, which is exactly why the result is hard to argue with by pointing at any one paragraph.&lt;/p&gt;

&lt;p&gt;The second sentence of that quote is a vendor instruction to whoever is reading the score, not a defence you construct. What has actually moved decisions is a separate subject, and we wrote it up from published casework in flagged, but you wrote it yourself. If editing is appropriate and permitted, the properties in that list are also the closest thing to a specification for doing it by hand, which is the approach in how to humanize AI text without a tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a 100 does not settle
&lt;/h2&gt;

&lt;p&gt;One thing worth knowing before you build any argument on the number being exaggerated: the published tuning runs the other way. Turnitin says that "In order to maintain this low rate of 1% for false positives, there is a chance that we might miss some AI written text in a document", and gives the direction of the error: "if we identify that 50% of a document is likely written by an AI tool, it could contain as much as 65% AI writing." Whatever else is going on, "the tool is built to over-report" is not the design the vendor describes.&lt;/p&gt;

&lt;p&gt;That does not make a 100 a finding. Turnitin states in three separate help pages that its model may misidentify human-written, AI-generated and AI-paraphrased text and should not be the sole basis for adverse action against a student. And the accuracy claim people quote at each other carries a qualifier that gets dropped in transit, which we took apart in what a 1% false positive rate means. There is also no published threshold at which a number becomes misconduct, in either direction: is 20% AI too high covers why the 20 in the interface is a display rule rather than a rule about you.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you wrote it, rewriting it is the wrong first move. It changes the object under discussion, and it answers a question nobody asked.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Where a rewriting tool fits, and where a 100 makes it useless
&lt;/h2&gt;

&lt;p&gt;Worth saying plainly, because it cuts against us: at 100, the thing HumanPen is normally good for has nothing to bite on. Upload the document together with the Turnitin or iThenticate report and only passages matched from the report are rewritten, with the rest preserved verbatim, and billing counts only the words actually rewritten. That is a real saving at 30%, where two thirds of the file never gets touched or charged for. At 100% the report has marked everything, so the scope is the document and the cost is a full pass. If you were hoping the report would narrow the job, a 100 is the one number where it does not.&lt;/p&gt;

&lt;p&gt;If a new report still flags passages, eligible results can continue lowering AI for free.&lt;/p&gt;

&lt;p&gt;None of that is a promise about a detection result, and we will not make one. No tool can tell you what a future model version will output on a document it has not seen, and anything offering a guaranteed score is describing something it cannot control. There are also cases where the tool is the wrong instrument entirely: if your position is that the work is yours, the number is not the object to be fixed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Does 100% mean every sentence I wrote was flagged?&lt;/strong&gt; No. The percentage is computed over qualifying text, which excludes lists, bullet points and other non-sentence structures, and Turnitin says the figure is not necessarily the percentage of the entire submission. A file with substantial tables, lists and a reference section can show 100% while large parts of it were never assessed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My essay is only 600 words. Is that the explanation?&lt;/strong&gt; It is the first thing to check. Turnitin's own account is that in documents of a few hundred words the prediction is mostly "all or nothing" because it is working from a single segment with no opportunity to overlap, and that a mix of AI-generated and original content can therefore be flagged as entirely AI-generated.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I saw the number in my own Turnitin view. Is that the AI score?&lt;/strong&gt; Almost certainly not. Turnitin says only instructors and administrators can see the AI indicator and that it is not visible to students, though instructors can download the AI report as a PDF and share it. A percentage you reached yourself is the similarity score, which has its own ordinary routes to 100.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can any tool guarantee the next report will be lower?&lt;/strong&gt; No, and treat the claim as a warning sign. Detector versions change, and nobody outside the vendor can commit to the output of a model version that has not run yet. What a revision service can define is scope and cost, not a score.&lt;/p&gt;

&lt;h2&gt;
  
  
  Working from a report that highlights everything?
&lt;/h2&gt;

&lt;p&gt;Upload the document with the AI report. Only the marked passages are rewritten, and billing counts only the words actually rewritten.&lt;/p&gt;




&lt;p&gt;Originally published at &lt;a href="https://humanpen.net/blog/turnitin-says-100-percent-ai?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=d67" rel="noopener noreferrer"&gt;https://humanpen.net/blog/turnitin-says-100-percent-ai?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=d67&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>writing</category>
      <category>productivity</category>
    </item>
    <item>
      <title>What a 1% false positive rate means when a university submits 75,000 papers</title>
      <dc:creator>Nylah Reynard</dc:creator>
      <pubDate>Sat, 22 Aug 2026 13:28:29 +0000</pubDate>
      <link>https://dev.to/yotta-fish/what-a-1-false-positive-rate-means-when-a-university-submits-75000-papers-44g</link>
      <guid>https://dev.to/yotta-fish/what-a-1-false-positive-rate-means-when-a-university-submits-75000-papers-44g</guid>
      <description>&lt;p&gt;"It has a 1% false positive rate" is the kind of sentence that sounds like a specification and behaves like a rounding error, right up until somebody multiplies it by their own volume.&lt;/p&gt;

&lt;p&gt;One university did that multiplication in public in 2023 and published the arithmetic along with the decision it made. What follows is that number, the two conditions that get dropped whenever it is repeated, and the qualifier the vendor attached to its own 1% figure and then dropped in the very next sentence. If you have ever had to explain a base rate to someone holding a single classification result, most of this will be familiar territory with unusually good source material.&lt;/p&gt;

&lt;h2&gt;
  
  
  The short answer
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;A false positive rate is a property of a population, not of your paper. Vanderbilt University put numbers on that in August 2023: it had submitted 75,000 papers to Turnitin in 2022, so if the AI detector had been running then, a 1% false positive rate would have meant "around 750 student papers could have been incorrectly labeled". It disabled the detector. Two conditions ride along with that sentence and both get dropped in the retelling: the detector was not running in 2022, which is why the source says "if", and the vendor's own 1% figure carries a qualifier that its own next sentence throws away.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The multiplication, in the university's own words
&lt;/h2&gt;

&lt;p&gt;Vanderbilt's Office of Learning and Innovation published a post on 16 August 2023 titled "Guidance on AI Detection and Why We're Disabling Turnitin's AI Detector". The decision itself is stated plainly: "Vanderbilt has decided to disable Turnitin's AI detection tool for the foreseeable future."&lt;/p&gt;

&lt;p&gt;The passage worth carrying around is the arithmetic:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"At the time of launch, Turnitin claimed that its detection tool had a 1% false positive rate (Chechitelli, 2023). To put that into context, Vanderbilt submitted 75,000 papers to Turnitin in 2022. If this AI detection tool was available then, around 750 student papers could have been incorrectly labeled as having some of it written by AI."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Nothing clever is happening there. It is one per cent of seventy-five thousand. But it converts a percentage into a number of documents, and that conversion is the whole reason error rates are hard to think about.&lt;/p&gt;

&lt;p&gt;Now read the second sentence again, starting at the word &lt;em&gt;if&lt;/em&gt;. The detector was not running when those 75,000 papers were submitted, which is what "if this AI detection tool was available then" means. So 750 is not a count of anything that happened at Vanderbilt or anywhere else. It is what one per cent of one university's real annual volume looks like written out. That is a smaller claim than the one the figure usually gets recruited for, and a much easier one to defend.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the number changes meaning depending on where you stand
&lt;/h2&gt;

&lt;p&gt;For a vendor, one in a hundred is a specification. For an institution, it is a yearly caseload. For you, it is neither — you are one document, and the rate says nothing about whether yours is the one.&lt;/p&gt;

&lt;p&gt;That last point cuts both ways, and it is where people overreach in both directions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;It does not mean your flag is probably wrong.&lt;/strong&gt; A 1% error rate on human-written papers is entirely compatible with most flagged papers being correctly flagged, depending on how many were AI-assisted to begin with.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It does mean "the tool is 99% accurate, so you must have done it" is not an argument.&lt;/strong&gt; A rate describes a population; it cannot tell you which member of that population is in front of you. And one per cent of a 75,000-paper year is hundreds of documents, so being in that band is unremarkable rather than exotic. Hundreds of documents is not hundreds of accusations, though, and the distance between those two is where most bad versions of this argument live.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The useful posture is neither "the detector is broken" nor "the detector is right". It is that a population statistic cannot adjudicate an individual case, and the vendor agrees in writing: its FAQ tells instructors not to treat the AI writing indicator's percentage as "the sole basis for action or a definitive grading measure".&lt;/p&gt;

&lt;h2&gt;
  
  
  The qualifier that keeps falling off
&lt;/h2&gt;

&lt;p&gt;Here is a detail that matters if you are ever going to quote the 1% figure at anybody.&lt;/p&gt;

&lt;p&gt;Turnitin's FAQ states the claim like this: it strives to keep its false positive rate — "incorrectly identifying fully human-written text as AI-generated" — "under 1% for documents with over 20% of AI writing."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For documents with over 20% of AI writing.&lt;/strong&gt; That is a substantial limit on the claim, and it does not survive the vendor's own restatement a sentence later, which reads: "In other words, we might flag a human-written document as AI-written for one out of every 100 fully-human written documents."&lt;/p&gt;

&lt;p&gt;The two sentences are not equivalent, and the second is the one that travels. If you use the figure, use the qualified version — partly because it is accurate, and mostly because someone on the other side of the table may know the qualifier is there.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which parts of a 2023 post survive being repeated
&lt;/h2&gt;

&lt;p&gt;The post is from August 2023. Part of it is arithmetic, which does not age. Part of it is a claim about what the vendor had published, which does. Sorting those before you quote anything is most of the work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The arithmetic is safe to repeat&lt;/strong&gt;, with the &lt;em&gt;if&lt;/em&gt; attached. One per cent of a large submission volume is a large number of documents, and nothing since 2023 touches that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The concern about non-native English writers is safe to repeat&lt;/strong&gt;, and it does not rest on this post at all. There is research behind it, and we went through what that research actually measured in AI detector bias against non-native English writing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The transparency complaint is the one to check before you repeat it.&lt;/strong&gt; Vanderbilt wrote that "Turnitin gives no detailed information as to how it determines if a piece of writing is AI-generated or not". Today's FAQ does describe how a score is assembled: sentences are extracted and segmented into overlapping sections, each segment is classified and given a value between 0 and 1, qualifying sentences inherit their segment's score, overlapping scores are pooled, and the pooled sentence scores are aggregated into a document score. Assert in a meeting that nothing has ever been published about how it works, and someone can put that paragraph in front of you.&lt;/p&gt;

&lt;p&gt;Read the sentence that follows it in the post, though, before deciding the objection was answered, because the objection is narrower than "tell us how it works". The complaint is that the tool "looks for patterns common in AI writing, but they do not explain or define what those patterns are". A description of how segment scores are combined is not a description of the patterns. The published mechanism and the published objection are about two different questions, and both can be quoted accurately on the same day.&lt;/p&gt;

&lt;p&gt;What we cannot tell you is when that FAQ passage first appeared. We have not dated it, so nothing above should be read as the vendor publishing it in answer to this post.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One more qualifier, and this one belongs to Vanderbilt.&lt;/strong&gt; The post describes the feature as arriving with "less than 24-hour advance notice, no option at the time to disable the feature". &lt;em&gt;At the time&lt;/em&gt; is in the original sentence. Quote it without those three words and you have converted a statement about the launch into a standing claim about the product. That is the same move as dropping "over 20%" from the 1% figure, just made by the other side of the argument.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use this without overplaying it
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Cite the date.&lt;/strong&gt; "In 2023, Vanderbilt disabled the tool and published this reasoning" is checkable and defensible. "Universities have abandoned AI detection" is neither.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Say what the arithmetic is an illustration of.&lt;/strong&gt; It travels because anyone can redo it with their own institution's volume, and it makes a real point: a small percentage still produces a caseload somebody has to review fairly. What it does not do is estimate accusations. Not every submission is eligible for a score, nobody outside the institution knows how much AI use there actually was, and a flag does not have to become a charge. We take that apart at more length in is 20% AI too high.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Do not claim it proves anything about your document.&lt;/strong&gt; It establishes that being wrongly flagged is an ordinary event at scale, which is a different and more modest claim.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check whether your own institution has published anything.&lt;/strong&gt; Look in the academic integrity policy and in whatever the teaching and learning centre puts out, not only the news page. A local statement outranks a distant one in every conversation you are likely to have.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep it out of your opening.&lt;/strong&gt; Process and provenance persuade first; statistics are what you reach for when someone argues that the number is self-evidently conclusive.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  If your institution still uses it
&lt;/h2&gt;

&lt;p&gt;If it does, the report in front of you is the object that matters rather than any of the above. What the percentage is a statistic of, and why the highlights and the number can disagree, is separate ground, covered in reading the AI writing report line by line.&lt;/p&gt;

&lt;p&gt;HumanPen enters only at the point where specific passages are marked and some of them need to change: the report sets the boundary, and unmarked paragraphs keep the wording you already have.&lt;/p&gt;

&lt;p&gt;None of that is an answer to a false positive. If your position is that you wrote it, rewriting it is the wrong move, and what has actually persuaded reviewers is a different subject entirely: the evidence that has moved a panel.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Does a 1% false positive rate mean my flag is probably wrong?&lt;/strong&gt; No. It is a rate across a population of human-written documents and says nothing about an individual case. It does mean that at institutional volume, wrongly flagged papers are an ordinary occurrence rather than a freak event.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where does the 750 figure come from?&lt;/strong&gt; From Vanderbilt's own post of 16 August 2023, applying the 1% figure to the 75,000 papers it submitted to Turnitin in 2022. Note the conditional: the detector was not running in 2022, so the sentence reads "if this AI detection tool was available then". It shows what one per cent of that university's volume looks like written out. It is not a record of 750 papers being wrongly flagged, and it is not a forecast for anyone else's institution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is the 1% claim unconditional?&lt;/strong&gt; No. Turnitin's stated target is under 1% "for documents with over 20% of AI writing". Its own restatement in the following sentence drops that qualifier, which is why the unqualified version circulates.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Have universities generally turned AI detection off?&lt;/strong&gt; That is not something this source supports. It documents one institution's decision in 2023, with its reasoning. Whether your institution uses it is a local question with a local answer.&lt;/p&gt;

&lt;h2&gt;
  
  
  When the passages are the problem
&lt;/h2&gt;

&lt;p&gt;Where a report marks specific passages and they need to change, the report can set the boundary.&lt;/p&gt;




&lt;p&gt;Originally published at &lt;a href="https://humanpen.net/blog/what-a-one-percent-false-positive-rate-means?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=d67" rel="noopener noreferrer"&gt;https://humanpen.net/blog/what-a-one-percent-false-positive-rate-means?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=d67&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>writing</category>
      <category>career</category>
    </item>
    <item>
      <title>Final manuscript check: AI disclosure, word count, citations and DOCX integrity</title>
      <dc:creator>Nylah Reynard</dc:creator>
      <pubDate>Sat, 22 Aug 2026 13:27:20 +0000</pubDate>
      <link>https://dev.to/yotta-fish/final-manuscript-check-ai-disclosure-word-count-citations-and-docx-integrity-58a1</link>
      <guid>https://dev.to/yotta-fish/final-manuscript-check-ai-disclosure-word-count-citations-and-docx-integrity-58a1</guid>
      <description>&lt;p&gt;This one is long, and it is a checklist for submitting an academic manuscript to a journal. I am posting it here because underneath the vocabulary it is a release checklist for a document, and the failure modes are ones you already know.&lt;/p&gt;

&lt;p&gt;Freeze the requirements before you touch the artifact. Run the passes in a fixed order, because each later pass invalidates the output of the earlier ones. Regenerate derived objects last, once nothing upstream is still moving. Then inspect the built output rather than the source, because the thing the reviewer opens is the build, not your working copy. The &lt;code&gt;Error! Reference source not found&lt;/code&gt; field in a Word file is the same class of bug as a stale generated header, and it ships just as easily.&lt;/p&gt;

&lt;h2&gt;
  
  
  Freeze the requirements before touching the final file
&lt;/h2&gt;

&lt;p&gt;The last pass should begin outside the manuscript. Save the target journal's author instructions, article-type page, AI policy and submission-portal prompts with the access date. The &lt;a href="https://www.icmje.org/recommendations/" rel="noopener noreferrer"&gt;ICMJE Recommendations&lt;/a&gt; say to follow an individual journal's instructions when they differ from ICMJE and currently identify the Recommendations as updated January 2026. That is the right hierarchy: the journal and the live portal govern the submission; a publisher page, society guideline or this checklist supplies context, not permission.&lt;/p&gt;

&lt;p&gt;Write a one-page requirement record before editing. Name the journal, manuscript type, deadline and time zone, required template, anonymisation model, reporting checklist, file types, limits and every portal-only question. Save the actual pages or PDFs, not only bookmarks: instructions can change during revision, and the record lets co-authors see which version you applied.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Requirement to freeze&lt;/th&gt;
&lt;th&gt;Record exactly&lt;/th&gt;
&lt;th&gt;Common last-pass failure&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Article type and structure&lt;/td&gt;
&lt;td&gt;Allowed sections, abstract form, heading order, title-page separation&lt;/td&gt;
&lt;td&gt;A research article is prepared under review or brief-report limits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Files and template&lt;/td&gt;
&lt;td&gt;Main document, title page, figures, tables, supplements, cover letter and required forms&lt;/td&gt;
&lt;td&gt;A file mentioned in the manuscript is never uploaded&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reporting requirement&lt;/td&gt;
&lt;td&gt;Applicable checklist or extension and where it must be uploaded&lt;/td&gt;
&lt;td&gt;The checklist is completed but omitted from the package&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Blind-review rule&lt;/td&gt;
&lt;td&gt;What must be removed from manuscript, properties, acknowledgements and file names&lt;/td&gt;
&lt;td&gt;Author identity remains in comments or document metadata&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deadline&lt;/td&gt;
&lt;td&gt;Date, clock time, time zone and whether final confirmation is required&lt;/td&gt;
&lt;td&gt;Upload starts before the deadline but confirmation occurs after it&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Resolve contradictions now. If the publisher policy says one thing but the journal page or portal asks something narrower, record both and ask the editorial office when the answer changes what you would disclose or upload. Do not silently choose the easier instruction. A dated written reply belongs in the submission record.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Freeze requirements, not assumptions: exact journal, exact article type, exact submission round and exact access date.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Classify actual AI uses and place each disclosure
&lt;/h2&gt;

&lt;p&gt;Do not answer an AI question from the product name alone. Reconstruct what the tool actually did: grammar correction, translation, prose generation, outlining, code generation, data analysis or figure creation can fall under different rules even when one application performed all of them. Use your work log and chat history; do not rely on a vague memory that the tool was used only for editing.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Actual use&lt;/th&gt;
&lt;th&gt;What to verify&lt;/th&gt;
&lt;th&gt;Likely disclosure location under ICMJE guidance&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Writing or language assistance&lt;/td&gt;
&lt;td&gt;Whether the journal exempts limited grammar/copy editing and how it defines the boundary&lt;/td&gt;
&lt;td&gt;Acknowledgements when disclosure is required&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data collection, analysis or code&lt;/td&gt;
&lt;td&gt;What input, model/version, method and human validation affected the reported work&lt;/td&gt;
&lt;td&gt;Methods&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Figure or image generation&lt;/td&gt;
&lt;td&gt;Whether it is permitted, how provenance is shown and whether the image represents data&lt;/td&gt;
&lt;td&gt;Methods plus any figure-specific declaration required by the journal&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Any reportable use in an ICMJE-governed submission&lt;/td&gt;
&lt;td&gt;Whether the manuscript statement and portal answer describe the same purposes&lt;/td&gt;
&lt;td&gt;Cover letter as well as the appropriate manuscript section&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://www.icmje.org/recommendations/browse/roles-and-responsibilities/defining-the-role-of-authors-and-contributors.html#four" rel="noopener noreferrer"&gt;ICMJE's current authorship guidance&lt;/a&gt; says AI tools cannot be authors or co-authors. It places writing assistance in Acknowledgements, use for data collection or analysis and figure generation in Methods, and says authors should disclose use in the cover letter too. Humans remain responsible for accuracy, attribution, source checking and plagiarism. Those rules apply to journals that use ICMJE guidance; other venues can require different wording, locations or prohibitions.&lt;/p&gt;

&lt;p&gt;For a cross-publisher comparison, use the separate AI disclosure policy guide, then re-open the target journal's own rules. Keep a row for each use: tool and version, date, purpose, affected section, output retained, data sent, human verification and disclosure location. The declaration should state actions, not advertise the tool or claim that AI merely 'helped.'&lt;/p&gt;

&lt;p&gt;Check the manuscript, acknowledgements, Methods, cover letter and portal answers as one system. A statement in one location does not automatically answer a separate portal question. If a use may have violated confidentiality, image or research-integrity rules, disclosure does not retroactively make it permissible; pause and give the editor or integrity office an accurate account before submission.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Classify by purpose, disclose in the required places, and make every version of the account consistent.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Define the word count, then edit in the only stable order
&lt;/h2&gt;

&lt;p&gt;There is no universal journal word-count formula. Record what this journal includes and excludes before trying to shorten anything: title page, structured or unstructured abstract, main text, quotations, footnotes, acknowledgements, declarations, table text, figure legends, references and online supplements may be treated differently. Also record separate limits for the title, abstract, highlights and individual sections.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://www.icmje.org/recommendations/browse/manuscript-preparation/preparing-for-submission.html#a" rel="noopener noreferrer"&gt;ICMJE manuscript-preparation guidance&lt;/a&gt; gives a useful medical-journal example: the text word count excludes the abstract, acknowledgements, tables, figure legends and references, and authors should also report a separate abstract word count. That is not a universal rule. Copying that definition into a humanities, engineering or even another medical journal can produce the wrong number. The target journal's definition controls.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pass&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;th&gt;Why this pass comes here&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1. Substantive revision or humanizing&lt;/td&gt;
&lt;td&gt;Make the argument accurate, clear and genuinely owned by the authors&lt;/td&gt;
&lt;td&gt;Later cuts should operate on approved meaning, not on text that will be rewritten again&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2. Condensing&lt;/td&gt;
&lt;td&gt;Meet the recorded scope without deleting required evidence, limitations or reporting items&lt;/td&gt;
&lt;td&gt;Compression after meaning is stable avoids counting and polishing text that will disappear&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3. Citation standardisation&lt;/td&gt;
&lt;td&gt;Apply the verified journal style to citations and references&lt;/td&gt;
&lt;td&gt;Earlier edits can move citations, merge claims and delete sources; formatting them first creates rework and stale fields&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4. Document-object update&lt;/td&gt;
&lt;td&gt;Refresh contents, cross-references, lists, numbering and linked fields&lt;/td&gt;
&lt;td&gt;Fields should resolve only after text, order and references have stopped moving&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;After each pass, recount using the same recorded method. Do not remove a reporting-checklist item merely because the main-text counter is high, and do not move substantive text into a caption or supplement unless the journal permits it and readers can still interpret the work. If the paper remains over the limit, keep a cut log: removed passage, reason, affected citation or cross-reference, and where essential material was relocated.&lt;/p&gt;

&lt;p&gt;Freeze high-risk content during language work: exact data, units, equations, code, search strategies, eligibility rules and required legal or ethics statements. The Methods and Results revision checklist explains how to separate expression from scientific invariants. A lower detector score or cleaner sentence never proves that a factual revision is correct.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reconcile citations, fields, figures and supplements
&lt;/h2&gt;

&lt;p&gt;Citation work has two layers. First verify evidence: every in-text citation still supports the claim beside it, quotations and page locators are accurate, no source became detached when sentences moved, and every cited item has one reference-list entry and vice versa. Only then standardise punctuation, ordering, names, titles, dates, identifiers and journal abbreviations to the verified journal style. Authors remain responsible for reference accuracy under ICMJE guidance; a reference manager or converter cannot assume that responsibility.&lt;/p&gt;

&lt;p&gt;Use the journal's named style and examples, not a generic label such as 'Harvard.' If the required variant is unclear, the Harvard variant guide shows how to locate the authoritative local specification. Convert a small sample containing your hardest source types, inspect it, then process the full list. Never repair a citation problem by sending the surrounding argument to an AI humanizer.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Object&lt;/th&gt;
&lt;th&gt;Final reconciliation&lt;/th&gt;
&lt;th&gt;Failure to look for&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Table of contents and heading fields&lt;/td&gt;
&lt;td&gt;Update all fields; compare headings and page numbers against the visible document&lt;/td&gt;
&lt;td&gt;Deleted heading remains or a new heading is absent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cross-references and numbering&lt;/td&gt;
&lt;td&gt;Refresh figure, table, equation, section and footnote references&lt;/td&gt;
&lt;td&gt;A field displays &lt;code&gt;Error! Reference source not found&lt;/code&gt; or points to the wrong number&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tables and figures&lt;/td&gt;
&lt;td&gt;Confirm numbering, first citation, title/legend, abbreviations, units, resolution and separate-file requirement&lt;/td&gt;
&lt;td&gt;Caption and file disagree, or a figure is uploaded but never cited&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Supplements&lt;/td&gt;
&lt;td&gt;Match every callout, label, filename and version to the uploaded item&lt;/td&gt;
&lt;td&gt;The manuscript cites Appendix S2 but the package contains an older S1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reference fields&lt;/td&gt;
&lt;td&gt;Refresh the manager output, then inspect the rendered text and stable identifiers&lt;/td&gt;
&lt;td&gt;A field is current but the source metadata itself is wrong&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Word fields are live document objects, not ordinary text. Copy-paste, unlinking or accepting changes can leave a visually plausible but stale number. Follow the Word fields and long-document guide, update on a working copy, reopen the file and search for field-error text. Then compare the abstract, main text, tables, figures, captions and supplements for the same sample size, label, unit and result.&lt;/p&gt;

&lt;h2&gt;
  
  
  Run this 12-step submission checklist in order
&lt;/h2&gt;

&lt;p&gt;Copy this list into the project record and add an owner, completion date and evidence link to each line. A tick should mean that someone opened the relevant source or file and verified it; it should not mean 'probably handled.'&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Save the governing instructions.&lt;/strong&gt; Archive the target journal author guide, article-type page, publisher and journal AI policies, portal wording and access dates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Confirm the submission contract.&lt;/strong&gt; Record manuscript type, every required file and template, reporting checklist, anonymisation rule, deadline, clock time and time zone.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Classify every AI use.&lt;/strong&gt; Map each purpose to the journal rule and required manuscript, cover-letter and portal disclosure; reconcile all versions of the statement.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Define the exact word-count scope.&lt;/strong&gt; Write down what is included and excluded plus separate title, abstract, highlight and section limits; save the counted values.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Complete substantive edits and humanizing first.&lt;/strong&gt; Verify every changed claim, number, qualifier and citation against the authors' source of truth.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Condense second.&lt;/strong&gt; Cut repetition and low-value framing while preserving required reporting items, evidence, uncertainty and limitations; recount with the same scope.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Standardise citations last.&lt;/strong&gt; Reconcile claims to sources, run the forward/reverse reference check, then apply the journal's exact style and inspect difficult source types.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Update every document object.&lt;/strong&gt; Refresh fields, contents, cross-references and numbering; reconcile tables, figures, captions, footnotes, equations and supplements with the text and upload set.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Produce and inspect a clean copy.&lt;/strong&gt; Resolve tracked changes and comments, inspect visible markup, headers and footers, then run metadata inspection on a duplicate rather than the sole source file.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Archive the working record.&lt;/strong&gt; Keep the source document, dated clean submission copy, requirement and policy snapshots, AI-use log, cut log and completed checklist with unambiguous versions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Upload the complete package.&lt;/strong&gt; Match each required file to the manifest, use intelligible filenames, verify the selected article type and replace stale versions rather than trusting upload order.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open the portal-generated PDF before confirming.&lt;/strong&gt; Read it page by page for conversion, order, identity, font, symbol, table, figure, link and supplement problems; correct the source or upload and regenerate until it matches the intended submission.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Use a manifest rather than memory: filename, purpose, source version, clean/anonymised status, required format, portal slot, uploaded checksum or timestamp, and reviewer initials. Include title page, main manuscript, figures, tables, supplements, cover letter, declarations, reporting checklist and any response document that this submission round requires. Mark genuinely inapplicable items as &lt;code&gt;N/A&lt;/code&gt; with a reason so an empty cell cannot be mistaken for completion.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This checklist reduces preventable submission errors; it does not certify journal compliance, research validity, acceptance or any detector result.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Create a clean file without destroying the evidence
&lt;/h2&gt;

&lt;p&gt;Keep the editable source with its history, then make a dated submission copy. In the source, resolve every tracked change and comment deliberately: accept or reject changes one by one where meaning matters, answer unresolved comments, and use Word's All Markup view to inspect deletions, formatting changes and comment threads. Turning off Track Changes or switching to No Markup only changes the view; it does not remove revisions.&lt;/p&gt;

&lt;p&gt;On the duplicate, use Word's &lt;code&gt;File &amp;gt; Info &amp;gt; Check for Issues &amp;gt; Inspect Document&lt;/code&gt;. &lt;a href="https://support.microsoft.com/en-us/office/collab-files/remove-hidden-data-and-personal-information-by-inspecting-documents-presentations-or-workbooks" rel="noopener noreferrer"&gt;Microsoft's Document Inspector guidance&lt;/a&gt; warns that removed information may not be recoverable and recommends working on a copy. The inspector can identify comments and revisions, document properties and personal information, headers, footers and watermarks, hidden text, custom XML and invisible content. Review each finding before removal.&lt;/p&gt;

&lt;p&gt;Document Inspector is not a complete anonymisation method. It cannot judge whether an acknowledgement names the lab, a self-citation reveals the authors, a filename contains an identity, or a screenshot exposes a path. It also does not replace visible All Markup review. Apply only the target journal's blind-review rule: removing every contextual clue can itself damage a methods section or required disclosure.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reopen the clean DOCX after inspection and verify it is not corrupted, protected unexpectedly or missing links and fields.&lt;/li&gt;
&lt;li&gt;Search for author names, institutions, initials, email addresses, grant identifiers, tracked-change balloons and &lt;code&gt;Error!&lt;/code&gt; field messages when blind review applies.&lt;/li&gt;
&lt;li&gt;Compare page count, section order, tables, figures, equations and reference-list ending against the reviewed source.&lt;/li&gt;
&lt;li&gt;Give source and clean copies distinct dated filenames; never overwrite the only version that preserves revision evidence.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Treat the portal PDF as the file the editor will see
&lt;/h2&gt;

&lt;p&gt;After upload, stop checking the local DOCX. Confirm the portal shows the intended article type, title, author order, affiliations, corresponding author, abstract, keywords, funding, conflicts, data statement, AI declaration and file designations. Compare manually entered metadata with the manuscript; a correct document does not repair a wrong portal field.&lt;/p&gt;

&lt;p&gt;Many systems assemble a review PDF or proof from uploaded files. Opening that generated PDF before final confirmation is a HumanPen workflow recommendation, not an ICMJE rule. Read from the first title-page element to the last supplement callout. Check file order, missing pages, anonymous versus named version, substituted fonts, mathematical symbols, superscripts, hyperlinks, line breaks, clipped tables, figure resolution, caption placement and reference characters.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;If the generated PDF is wrong&lt;/th&gt;
&lt;th&gt;Correct response&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;The source DOCX is also wrong&lt;/td&gt;
&lt;td&gt;Correct the source, produce a new dated clean copy, replace the upload and regenerate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Only portal conversion is wrong&lt;/td&gt;
&lt;td&gt;Use the journal's permitted alternate format or contact support/editorial staff; preserve screenshots and ticket details&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The wrong file or order was selected&lt;/td&gt;
&lt;td&gt;Remove or replace it in the designated slot, then inspect the newly generated PDF from the beginning&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A required supplement is not merged&lt;/td&gt;
&lt;td&gt;Verify that the portal lists it correctly and that the manuscript callout and filename agree; follow the journal's review-display convention&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Only confirm after a named author has reviewed the generated artifact and the portal summary. Save the final PDF or confirmation preview when the system permits, the submission identifier, timestamp and receipt. If a co-author makes a late change, do not patch just the portal copy: return to the versioned source, rerun the affected checks, replace the files and inspect the regenerated PDF again.&lt;/p&gt;

&lt;p&gt;If a revision service handles the DOCX prose for you, it does not submit to the journal or guarantee policy compliance, acceptance or a detector outcome. Keep the source, compare the returned document, verify citations and invariants, and then resume this checklist at the appropriate step.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Final means reproducible: another co-author can identify the governing rules, the exact clean file, every uploaded component and the PDF that was actually approved.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Ready to prepare the journal-submission copy?
&lt;/h2&gt;

&lt;p&gt;Whichever tool revises the prose in the DOCX, the policy, citation, file and portal checks in this article are the part that decides whether the submission holds up.&lt;/p&gt;




&lt;p&gt;Originally published at &lt;a href="https://humanpen.net/blog/final-manuscript-pre-submission-checklist?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=d67" rel="noopener noreferrer"&gt;https://humanpen.net/blog/final-manuscript-pre-submission-checklist?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=d67&lt;/a&gt;&lt;/p&gt;

</description>
      <category>writing</category>
      <category>productivity</category>
      <category>documentation</category>
      <category>career</category>
    </item>
    <item>
      <title>Does Turnitin detect AI in a PDF?</title>
      <dc:creator>Nylah Reynard</dc:creator>
      <pubDate>Sat, 22 Aug 2026 13:25:11 +0000</pubDate>
      <link>https://dev.to/yotta-fish/does-turnitin-detect-ai-in-a-pdf-4lhf</link>
      <guid>https://dev.to/yotta-fish/does-turnitin-detect-ai-in-a-pdf-4lhf</guid>
      <description>&lt;p&gt;Every few weeks someone asks whether exporting to PDF changes what a detector sees. It is a format question wearing a detection costume, and the vendor answers the format half in one line on a page that takes a minute to read. I checked it again today.&lt;/p&gt;

&lt;p&gt;The half worth more to anyone who works with documents is the other one: what a PDF export does to the file. Fields, generated tables of contents, cross-references and automatic numbering stop being live objects and become printed text, and the round trip back out of a PDF is where structure quietly breaks.&lt;/p&gt;

&lt;h2&gt;
  
  
  The short answer
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Yes. PDF is one of four file types on Turnitin's accepted list for an AI Writing Report, alongside .docx, .txt and .rtf. Submitting as a PDF does not remove your document from AI writing analysis. What the format does change is what your file contains, and that has real consequences elsewhere in your submission.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The accepted file-type list
&lt;/h2&gt;

&lt;p&gt;Straight from the &lt;a href="https://guides.turnitin.com/hc/en-us/articles/28234943089933-File-requirements-for-an-AI-Writing-Report" rel="noopener noreferrer"&gt;file requirements for an AI Writing Report&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Accepted file types: .docx, .pdf, .txt, .rtf"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The same short list also sets the language rule: "File must be written in a supported language: English, Spanish, Japanese". That line is a few days behind the product — Modern Standard Arabic was added on 18 August 2026 and the requirements page has not been edited since — so treat it as four. If the language rule is your question rather than the format, we took it apart separately in can Turnitin detect AI in non-English submissions.&lt;/p&gt;

&lt;p&gt;That is the entire format answer. There is no separate PDF pathway, no lighter treatment, nothing in the published requirements that treats one accepted type differently from another.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the report reads inside your PDF
&lt;/h2&gt;

&lt;p&gt;The same thing it reads inside a Word file: prose. Turnitin calls it qualifying text, and describes it on the page about &lt;a href="https://guides.turnitin.com/hc/en-us/articles/22774058814093-Using-the-AI-Writing-Report" rel="noopener noreferrer"&gt;using the AI Writing Report&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"This qualifying text includes only prose sentences, meaning that we only analyze blocks of text that are written in standard grammatical sentences and do not include other types of writing such as lists, bullet points (short non-sentence structures), or other non-sentence structures."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then: "This percentage is not necessarily the percentage of the entire submission."&lt;/p&gt;

&lt;p&gt;So the percentage on a thesis PDF is a statistic over the running prose inside it, not over the pages. Turnitin says elsewhere that a document containing several writing types "would result in a disparity between the percentage and the highlights", which is the documented reason your highlighted passages never look like they add up to the number. More on reading that mismatch in how to read a Turnitin AI writing report.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tables and the reference list
&lt;/h2&gt;

&lt;p&gt;Two specifics that matter for anything thesis-shaped, both from Turnitin's &lt;a href="https://guides.turnitin.com/hc/en-us/articles/28294949544717-AI-writing-detection-model" rel="noopener noreferrer"&gt;AI writing detection model release notes&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Prose inside tables is processed: "We are now able to process long-form prose text in tables." The following line adds the condition that gets forgotten: "Resubmit to reprocess existing submissions that contain tables." Existing reports do not update themselves.&lt;/p&gt;

&lt;p&gt;Bibliographies are excluded: "We have fixed a bug that was occasionally highlighting AI writing within references listed in a bibliography. Bibliographies are now excluded when processing the AI writing report." Same catch, same wording: "Resubmit to reprocess existing submissions that contain highlighted reference sections."&lt;/p&gt;

&lt;p&gt;If you are looking at a report with a highlighted reference list, check the date it was generated before you conclude anything about your references. Also check which report you are holding: Turnitin's documentation says AI writing highlights "are not visible in the Similarity Report" at all, and matching reference entries are the ordinary case in a similarity report, since a citation style exists to make everyone format the same source the same way.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a PDF export actually changes
&lt;/h2&gt;

&lt;p&gt;Not the detection. The document.&lt;/p&gt;

&lt;p&gt;Exporting to PDF flattens the machinery in a Word file: fields, the generated table of contents, cross-references and automatic numbering stop being live objects and become printed text. That matters when you still have revisions ahead of you, and it matters more when the round trip goes the other way, because bringing text back out of a PDF and into a document is where numbering and structure get quietly broken.&lt;/p&gt;

&lt;p&gt;The practical rule is boring. Keep revising in the source file. Export the PDF last, from the version you are actually submitting.&lt;/p&gt;

&lt;h2&gt;
  
  
  The size of the document changes the behaviour
&lt;/h2&gt;

&lt;p&gt;One line worth carrying:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"In shorter documents where there are only a few hundred words, the prediction will be mostly 'all or nothing' because we're predicting on a single segment without the opportunity to overlap."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And its follow-up: "This means that some text that is a mix of AI-generated and original content could be flagged as entirely AI-generated." A one-page PDF is not a smaller version of the same measurement. It is a blunter one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Whether you see a score at all
&lt;/h2&gt;

&lt;p&gt;Two separate gates, and neither is about your file. Turnitin says AI writing detection "is only be available to customers that license Turnitin Originality" (their grammar), with an add-on route for iThenticate 2.0 accounts. And it says only instructors and administrators can see the indicator, adding that "with the PDF download feature, instructors can download and share the AI report with students".&lt;/p&gt;

&lt;p&gt;That last part is the PDF that most students actually end up holding: a PDF of the report, not a PDF they submitted. Worth being precise about which one is in the conversation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Is submitting a PDF safer than submitting a Word file?&lt;/strong&gt; No. Both are on the same accepted list, and the analysis described in Turnitin's documentation does not distinguish between them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What about a PDF that is only scanned page images?&lt;/strong&gt; There is no prose to extract from an image, and treating that as a way through is a bad plan on its own terms. A page-image PDF cannot be searched, quoted or annotated by whoever is reading it, which is usually a submission requirement somewhere in the paperwork. And Turnitin's own line is that the AI score "should not be used as the sole basis for adverse actions against a student", which means the person, not the statistic, is doing the deciding. Removing the statistic does not remove the reader.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My PDF got a similarity score but no AI percentage.&lt;/strong&gt; The two are independent. Turnitin's documentation says the similarity score and the AI writing percentage "are completely independent and do not influence each other". Missing AI numbers point at the licence, the language rules or who is allowed to see the indicator, not at your file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does a PowerPoint export to PDF get an AI report?&lt;/strong&gt; The PDF is on the accepted list, so mechanically yes. But slides are mostly bullets, and bullets are not qualifying text, so the prose the report has to work with may be a small fraction of what is on the slides.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rewriting from a report rather than from scratch?
&lt;/h2&gt;

&lt;p&gt;Upload the document and the AI Writing Report. Only the highlighted passages get rewritten.&lt;/p&gt;




&lt;p&gt;Originally published at &lt;a href="https://humanpen.net/blog/does-turnitin-detect-ai-in-pdf?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=d67" rel="noopener noreferrer"&gt;https://humanpen.net/blog/does-turnitin-detect-ai-in-pdf?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=d67&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>writing</category>
      <category>pdf</category>
      <category>documentation</category>
    </item>
    <item>
      <title>Why your AI writing score is missing, inconsistent, or will not download</title>
      <dc:creator>Nylah Reynard</dc:creator>
      <pubDate>Sat, 22 Aug 2026 13:23:17 +0000</pubDate>
      <link>https://dev.to/yotta-fish/why-your-ai-writing-score-is-missing-inconsistent-or-will-not-download-59h6</link>
      <guid>https://dev.to/yotta-fish/why-your-ai-writing-score-is-missing-inconsistent-or-will-not-download-59h6</guid>
      <description>&lt;p&gt;Turnitin keeps three public known-issues pages. I had never opened any of them until I went looking for why one score was being reported two different ways, and it turned out the vendor had already written the answer down.&lt;/p&gt;

&lt;p&gt;If you have ever shipped anything that displays a computed number, the entries below will feel familiar in a slightly uncomfortable way: the same value rounded at two different stages and rendered in two places, an error string that enumerates causes that do not apply to the case in front of it, a browser-specific bug that hides a control entirely, and a download that fails by region. Here they are, quoted, with the dates attached.&lt;/p&gt;

&lt;h2&gt;
  
  
  The short answer
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Turnitin publishes known-issues pages, and several live entries concern the AI writing indicator directly. Among them: the score shown in the assignment inbox can differ slightly from the score inside the full report because of rounding at different stages; during processing the interface can display an "unavailable" message giving reasons that do not apply; the indicator can be hidden entirely by a browser issue affecting Safari; and downloading the AI report can fail depending on the user's location. None of these are statements about your writing.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The pages exist, and almost nobody reads them
&lt;/h2&gt;

&lt;p&gt;There are three of them, all public and none behind a login: a general known-issues page, one for add-on products (which is where AI writing detection lives, under the Originality add-on), and one for LMS integrations.&lt;/p&gt;

&lt;p&gt;They are dated. The general page carried "Similarity Report issues as of: 27 July 2026" when we read it; the add-on page said "All Originality add-on issues as of: 1 July 2026"; the integrations page said it had been updated 20 days earlier. That dating is the important part, and it cuts both ways — &lt;strong&gt;anything below may be fixed by the time you read this, and new entries may have appeared.&lt;/strong&gt; The pages are the source, not this article.&lt;/p&gt;

&lt;p&gt;One more number worth noticing: the general page had been marked helpful by 60 out of 408 people who voted. Make of that what you like about how it reads to someone arriving in a panic.&lt;/p&gt;

&lt;h2&gt;
  
  
  The rounding gap between two places the same score appears
&lt;/h2&gt;

&lt;p&gt;This one explains a specific and maddening experience, and it is documented in one paragraph:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"We're aware of an issue where users may notice a small discrepancy between the AI writing detection score shown in the assignment inbox and the score displayed within the full report. This difference is caused by the way scores are rounded at different stages of the calculation and display process."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Turnitin adds that "Although the discrepancy is minor, it may cause confusion when comparing scores across the interface", and then that "We are working to implement a resolution as soon as possible." That last sentence is also the shelf life of this entry: a vendor that says it is fixing something is a vendor whose known-issues page will stop saying it.&lt;/p&gt;

&lt;p&gt;So if you have been told one number and then seen a different one, the difference may be entirely presentational. That is worth knowing before anyone builds an argument on a one-point gap, in either direction.&lt;/p&gt;

&lt;h2&gt;
  
  
  The error message that may not be about your file
&lt;/h2&gt;

&lt;p&gt;The entry to know if you have ever been told your submission was excluded:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"We're aware of an issue where, during the AI writing detection processing period, users may briefly see an error message stating that 'AI writing detection is unavailable for this submission.' This message includes reasons such as 'excluded by instructor,' 'unsupported file type,' or 'resubmission excluded,' even though these do not apply to the submission in question."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And the resolution: "Once processing is complete, the expected AI score and report are displayed as normal."&lt;/p&gt;

&lt;p&gt;Three specific, plausible, alarming reasons — all of which the vendor says can appear while nothing of the kind is true. If someone has quoted one of those phrases to you, it is worth asking when they looked.&lt;/p&gt;

&lt;h2&gt;
  
  
  When the indicator is not there at all
&lt;/h2&gt;

&lt;p&gt;Two documented causes, neither of them about your document.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A browser issue.&lt;/strong&gt; "There's a known issue that is causing the AI writing administrator setting and the AI writing indicator to be hidden from users. This is a browser issue primarily impacting users on the Safari browser." The published workaround is to clear the cache, and to make sure pop-ups from Turnitin are allowed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A route through the Authorship report.&lt;/strong&gt; A separate entry describes non-US Feedback Studio with Originality users being unable to access AI writing detection when launching the document viewer from the Authorship Report.&lt;/p&gt;

&lt;p&gt;If an instructor tells you the AI report "isn't available", these are worth knowing about, because both are fixed by doing something different rather than by concluding anything.&lt;/p&gt;

&lt;h2&gt;
  
  
  Downloading, and where you are sitting
&lt;/h2&gt;

&lt;p&gt;The general page carries an entry titled "AI download issue based on geographical location":&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"We are aware that a user's geographical location, specifically mainland China, may prevent the download of the AI report. Users of the Classic Standard assignment may also encounter an issue where the score does not appear in the Classic Similarity Report. Our engineering team is aware and actively exploring a solution."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This matters for a large group of people, and it is easy to misread as a problem with the submission. It is a documented access problem with a named location and an open resolution status.&lt;/p&gt;

&lt;p&gt;Two neighbouring download entries are worth a glance for the same reason. A period in the filename — not counting the extension — can cause a file to be left out of a bulk download. And downloads of the new Similarity Report view can produce character errors in non-Latin languages, with a separate entry for formatting errors in Arabic.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 500-character floor on Flags
&lt;/h2&gt;

&lt;p&gt;Slightly outside the AI indicator but in the same report, and it answers a question people ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Submitted documents must contain at least 500 characters to enable the Flags feature in the classic and new Similarity Report experience."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The known issue attached is that submissions below that threshold can incorrectly display a Flag icon in the assignment inbox, and opening it produces an error. The published workaround is to check whether the submission meets the 500-character requirement first, and if it does not, "the flag report can be disregarded".&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use any of this without overplaying it
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Check the pages before you argue about a number.&lt;/strong&gt; They are public, dated, and take two minutes. If your exact symptom is listed, you have a much better opening than a theory.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quote the entry, not the conclusion.&lt;/strong&gt; "There is a known issue where the inbox score and the report score differ because of rounding" is checkable. "The tool is unreliable" is not, and invites an argument you cannot win.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Note the date.&lt;/strong&gt; These entries get resolved — there is a Resolved tab on the pages. An entry that was live when you were flagged may be gone when someone else looks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Do not stretch it.&lt;/strong&gt; A rounding discrepancy between two displays says nothing about whether the underlying score is right, and a download failure says nothing at all about your text. Claiming more than the entry says is how a good point gets discarded.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Separate this from reading the report itself.&lt;/strong&gt; What each part of the report means is a different question, and we go through it in how to read a Turnitin AI writing report. The two numbers on a submission are also independent of each other, which we set out in the AI and Similarity reports side by side.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  When the number turns out to be real
&lt;/h2&gt;

&lt;p&gt;Most of the time it will be, and then the useful object is the set of highlighted passages rather than the total.&lt;/p&gt;

&lt;p&gt;HumanPen works from exactly that: give it the document and the report, and the passages carrying highlights are the ones it edits, while everything unmarked keeps the wording you wrote.&lt;/p&gt;

&lt;p&gt;None of that helps with a missing score or a failed download. For those, the pages above are the whole answer we have.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The score in the inbox and the score in the report are different. Which is right?&lt;/strong&gt; Turnitin documents this as a known issue caused by rounding at different stages of calculation and display, and describes the discrepancy as minor. It is not a sign that one of them is wrong about your writing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My report says AI detection is unavailable because of an unsupported file type. Is that real?&lt;/strong&gt; It may not be. Turnitin documents a known issue where that message, and reasons including "excluded by instructor" and "resubmission excluded", appear during processing even when they do not apply to the submission.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why can't the AI report be downloaded?&lt;/strong&gt; One published entry attributes download failures to the user's geographical location, naming mainland China specifically, with a resolution described as being explored.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Are these issues permanent?&lt;/strong&gt; No. The pages are dated, carry a Resolved tab, and change. Check the current page rather than relying on any summary of it, including this one.&lt;/p&gt;

&lt;h2&gt;
  
  
  When the score is real, work from the highlights
&lt;/h2&gt;

&lt;p&gt;Give it the document and the report, and only the marked passages are edited.&lt;/p&gt;




&lt;p&gt;Originally published at &lt;a href="https://humanpen.net/blog/why-your-ai-score-is-missing-or-inconsistent?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=d67" rel="noopener noreferrer"&gt;https://humanpen.net/blog/why-your-ai-score-is-missing-or-inconsistent?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=d67&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>writing</category>
      <category>documentation</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Best Freelance Writing Platforms 2026</title>
      <dc:creator>Sylvia A Sinatra</dc:creator>
      <pubDate>Sat, 22 Aug 2026 13:08:59 +0000</pubDate>
      <link>https://dev.to/sinatra182/best-freelance-writing-platforms-2026-41f5</link>
      <guid>https://dev.to/sinatra182/best-freelance-writing-platforms-2026-41f5</guid>
      <description>&lt;h1&gt;
  
  
  Best Freelance Writing Platforms 2026
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In 2026, earning money online is more accessible than ever. This guide covers&lt;br&gt;
real methods that pay — no fluff.&lt;/p&gt;

&lt;h2&gt;
  
  
  Methods That Work
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Microtasks&lt;/strong&gt; — small tasks on SproutGigs, earn crypto or PayPal.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Airdrop Farming&lt;/strong&gt; — join testnets, claim tokens pre-listing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content Writing&lt;/strong&gt; — publish on revenue-share platforms.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Freelance&lt;/strong&gt; — sell skills on Upwork, Fiverr.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Staking &amp;amp; Nodes&lt;/strong&gt; — passive income from crypto.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;Sign up, verify email, finish onboarding, then execute consistently.&lt;br&gt;
Payouts stack and withdraw to USDT wallets.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Consistency beats intensity. Start today, compound daily.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Tags: freelance, writing, content&lt;/em&gt;&lt;/p&gt;

</description>
      <category>freelance</category>
      <category>writing</category>
      <category>content</category>
    </item>
    <item>
      <title>How to Build a Profitable API Documentation Service</title>
      <dc:creator>qing</dc:creator>
      <pubDate>Sat, 22 Aug 2026 12:00:55 +0000</pubDate>
      <link>https://dev.to/qingluan/how-to-build-a-profitable-api-documentation-service-am0</link>
      <guid>https://dev.to/qingluan/how-to-build-a-profitable-api-documentation-service-am0</guid>
      <description>&lt;h1&gt;
  
  
  How to Build a Profitable API Documentation Service
&lt;/h1&gt;

&lt;p&gt;tags: api, writing, money, freelance&lt;/p&gt;




&lt;p&gt;tags: api, money, passive, startup&lt;/p&gt;




&lt;p&gt;tags: api, writing, money, freelance&lt;/p&gt;




&lt;p&gt;tags: api, writing, money, freelance&lt;/p&gt;




&lt;p&gt;tags: automation, money, saas, startup&lt;/p&gt;




&lt;p&gt;tags: api, money, passive, startup&lt;/p&gt;




&lt;p&gt;tags: api, money, passive, startup&lt;/p&gt;




&lt;p&gt;tags: api, money, passive, startup&lt;/p&gt;




&lt;p&gt;tags: wordpress, money, passive, programming&lt;/p&gt;




&lt;p&gt;tags: wordpress, money, passive, programming&lt;/p&gt;




&lt;p&gt;tags: wordpress, money, passive, programming&lt;/p&gt;




&lt;p&gt;tags: teaching, money, content, career&lt;/p&gt;




&lt;p&gt;tags: teaching, money, content, career&lt;/p&gt;




&lt;p&gt;tags: youtube, money, content, passive&lt;/p&gt;




&lt;p&gt;tags: youtube, money, content, passive&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, docker, devops, advanced&lt;/p&gt;




&lt;p&gt;tags: python, api, tutorial, programming&lt;/p&gt;




&lt;p&gt;tags: python, api, tutorial, programming&lt;/p&gt;




&lt;p&gt;tags: python, api, tutorial, programming&lt;/p&gt;




&lt;p&gt;tags: python, api, tutorial, programming&lt;/p&gt;




&lt;p&gt;tags: python, api, tutorial, programming&lt;/p&gt;




&lt;p&gt;tags: python, security, tutorial, tools&lt;/p&gt;




&lt;p&gt;tags: python, security, tutorial, tools&lt;/p&gt;




&lt;p&gt;tags: python, security, tutorial, tools&lt;/p&gt;




&lt;p&gt;Imagine typing your master key once and instantly unlocking passwords for every site you visit, all stored in a file that looks like gibberish to anyone who tries to peek. That’s the power of building your own password manager in Python: you get total control over your data, learn critical security concepts, and end up with a tool you can actually use today.&lt;/p&gt;

&lt;p&gt;Security experts constantly warn against saving passwords in plain text, yet many developers still rely on browser storage or insecure notes. By building a custom manager, you enforce encryption by default and create a CLI tool that fits your workflow perfectly. Let’s dive into creating a secure, command-line password manager that encrypts your credentials using the industry-standard &lt;code&gt;cryptography&lt;/code&gt; library.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Build Your Own Password Manager?
&lt;/h2&gt;

&lt;p&gt;Before we write code, it’s worth understanding the security mindset behind this project. Most "password manager" tutorials skip the most critical part: &lt;strong&gt;encryption&lt;/strong&gt;. Storing passwords in a &lt;code&gt;.txt&lt;/code&gt; file is a security nightmare. If that file gets stolen, every account is compromised.&lt;/p&gt;

&lt;p&gt;We’re going to use &lt;strong&gt;Fernet&lt;/strong&gt;, a symmetric encryption scheme provided by the &lt;code&gt;cryptography&lt;/code&gt; library. Fernet ensures that your data is authenticated and encrypted, meaning even if someone modifies the file, the system will detect the tampering and refuse to decrypt it. This approach gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Confidentiality&lt;/strong&gt;: Passwords are unreadable without the key.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integrity&lt;/strong&gt;: Any modification to the file breaks decryption.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Simplicity&lt;/strong&gt;: A single Python script handles everything without complex databases.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 1: Install the Necessary Libraries
&lt;/h2&gt;

&lt;p&gt;You’ll need Python 3.11 or later. If you haven’t installed it yet, download it from python.org. Once you’re set up, install the required libraries via pip:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;cryptography pyperclip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;cryptography&lt;/code&gt;: Provides the Fernet encryption module.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;pyperclip&lt;/code&gt;: Allows your manager to automatically copy passwords to your clipboard (a handy feature for daily use).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 2: Design the Core Class Structure
&lt;/h2&gt;

&lt;p&gt;We’ll build a &lt;code&gt;PasswordManager&lt;/code&gt; class that handles key generation, file creation, encryption, and decryption. This keeps our code organized and reusable.&lt;/p&gt;

&lt;p&gt;The class will have these main methods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;generate_key()&lt;/code&gt;: Creates a secure master key.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;create_password_file()&lt;/code&gt;: Initializes an empty encrypted file.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;add_password(site, password)&lt;/code&gt;: Encrypts and saves a new password.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;get_password(site)&lt;/code&gt;: Decrypts and retrieves a password for a given site.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;list_passwords()&lt;/code&gt;: Shows all stored site names.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 3: Write the Working Code
&lt;/h2&gt;

&lt;p&gt;Here’s the complete, runnable script. Save this as &lt;code&gt;password_manager.py&lt;/code&gt; and run it in your terminal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;cryptography.fernet&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Fernet&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pyperclip&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;copy&lt;/span&gt;

&lt;span class="n"&gt;MASTER_KEY_FILE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;master.key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;PASSWORD_FILE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;passwords.encrypted&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PasswordManager&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_load_or_generate_key&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cipher&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Fernet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_load_or_generate_key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MASTER_KEY_FILE&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MASTER_KEY_FILE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rb&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Fernet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generate_key&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MASTER_KEY_FILE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;wb&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Master key generated and saved to master.key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_password_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PASSWORD_FILE&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PASSWORD_FILE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;wb&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cipher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Password file created.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add_password&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PASSWORD_FILE&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_password_file&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PASSWORD_FILE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rb&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;encrypted_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="n"&gt;decrypted_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cipher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;encrypted_data&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;entries&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;decrypted_data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;decrypted_data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;splitlines&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="n"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;

        &lt;span class="n"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;
        &lt;span class="n"&gt;new_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;:&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

        &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PASSWORD_FILE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;wb&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cipher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt;

        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Password for &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; added successfully.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_password&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PASSWORD_FILE&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;No password file found. Add a password first.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;

        &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PASSWORD_FILE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rb&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;encrypted_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;decrypted_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cipher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;encrypted_data&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Error: Password file is corrupted or key is invalid.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;decrypted_data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;No passwords stored yet.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;

        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;decrypted_data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;splitlines&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Password for &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="nf"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Password copied to clipboard!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;

        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;No password found for &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;list_passwords&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PASSWORD_FILE&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;No password file found.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;

        &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PASSWORD_FILE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rb&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;encrypted_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;decrypted_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cipher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;encrypted_data&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Error: Password file is corrupted.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;decrypted_data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;No passwords stored yet.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;

        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Stored sites:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;decrypted_data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;splitlines&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;site&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; - &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;pm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;PasswordManager&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_password_file&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;1. Add Password&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;2. Get Password&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;3. List Passwords&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;4. Exit&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;choice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Choose an option: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;choice&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;site&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Site name: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Password: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_password&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;choice&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;site&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Site name: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_password&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;choice&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;list_passwords&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;choice&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;4&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Exiting...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Invalid option.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How to Use It TODAY
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Run the script&lt;/strong&gt;: &lt;code&gt;python password_manager.py&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Add a password&lt;/strong&gt;: Choose option &lt;code&gt;1&lt;/code&gt;, enter a site name (e.g., &lt;code&gt;github.com&lt;/code&gt;) and your password.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Retrieve a password&lt;/strong&gt;: Choose option &lt;code&gt;2&lt;/code&gt;, enter the site name. The password will be printed and &lt;strong&gt;automatically copied to your clipboard&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;List all sites&lt;/strong&gt;: Choose option &lt;code&gt;3&lt;/code&gt; to see what’s stored.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Your master key is saved in &lt;code&gt;master.key&lt;/code&gt;. &lt;strong&gt;Never share this file&lt;/strong&gt;. If you lose it, you lose access to all your passwords. Consider backing it up to an encrypted drive or a secure cloud storage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security Best Practices
&lt;/h2&gt;

&lt;p&gt;Building the tool is step one; using it securely is step two. Here are critical tips:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Backup your key&lt;/strong&gt;: Store &lt;code&gt;master.key&lt;/code&gt; in a separate, secure location.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use strong passwords&lt;/strong&gt;: Since you’re managing passwords, ensure each one is unique and long (12+ characters).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Limit file access&lt;/strong&gt;: Ensure &lt;code&gt;passwords.encrypted&lt;/code&gt; and &lt;code&gt;master.key&lt;/code&gt; have restricted permissions (&lt;code&gt;chmod 600&lt;/code&gt; on Linux/Mac).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test integrity&lt;/strong&gt;: Try editing &lt;code&gt;passwords.encrypted&lt;/code&gt; manually. The script should refuse to decrypt it, confirming integrity protection.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What’s Next?
&lt;/h2&gt;

&lt;p&gt;You now have a fully functional, encrypted password manager. But you can go further:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Add a GUI&lt;/strong&gt;: Use &lt;code&gt;Streamlit&lt;/code&gt; or &lt;code&gt;Tkinter&lt;/code&gt; for a visual interface.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integrate with browsers&lt;/strong&gt;: Create a script that auto-fills passwords using browser automation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloud sync&lt;/strong&gt;: Store the encrypted file in a private cloud bucket (e.g., AWS S3) for access across devices.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The beauty of this project is that it’s modular. You can expand it without rewriting the core encryption logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start Protecting Your Data Now
&lt;/h2&gt;

&lt;p&gt;Don’t wait for a security breach to take your password management seriously. This script gives you immediate, practical control over your credentials while teaching you real encryption techniques.&lt;/p&gt;

&lt;p&gt;Run the code, add your first password, and experience the confidence of having your data encrypted by default. If you found this helpful, share it with a fellow developer, and drop a comment below with&lt;/p&gt;




&lt;p&gt;&lt;em&gt;If you found this helpful, consider &lt;a href="https://ko-fi.com/qingluan" rel="noopener noreferrer"&gt;buying me a coffee ☕&lt;/a&gt; — it keeps these articles coming!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Also check out my AI tools collection: &lt;a href="https://ai.xn--4ds5cia.xn--rhqv96g/" rel="noopener noreferrer"&gt;AI 次元世界&lt;/a&gt; — free AI tools for developers.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>api</category>
      <category>writing</category>
      <category>money</category>
      <category>freelance</category>
    </item>
    <item>
      <title>Why Counting Japanese Characters Is a Nightmare for Writers - How to Learn</title>
      <dc:creator>Haru</dc:creator>
      <pubDate>Sat, 22 Aug 2026 11:47:12 +0000</pubDate>
      <link>https://dev.to/haru_mojisu/why-counting-japanese-characters-is-a-nightmare-for-writers-how-to-learn-5bf2</link>
      <guid>https://dev.to/haru_mojisu/why-counting-japanese-characters-is-a-nightmare-for-writers-how-to-learn-5bf2</guid>
      <description>&lt;p&gt;&lt;strong&gt;Japanese Characters&lt;/strong&gt; frustrate writers because one “character” isn’t one letter. Hiragana, katakana, and kanji sit in the same sentence, so a naive counter treats meaning units, syllables, and foreign loans as if they were English glyphs. That mismatch breaks word limits, SEO targets, and manuscript stats before you even finish a draft.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Is Counting Japanese Characters Hard?
&lt;/h2&gt;

&lt;p&gt;Counting fails because three scripts share one page. Horizontal lines run left to right in many school texts, while novels and upper-level material often run vertical, top to bottom and right to left. You start at the top of the rightmost column and finish at the bottom of the leftmost one. A tool that only walks Latin-style rows will miss columns, double-count spacing, or split compounds. So your total drifts even when the text itself is fine.&lt;/p&gt;

&lt;p&gt;👉 Read the full guide here: &lt;a href="https://telegra.ph/%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%81%AE%E6%96%87%E5%AD%97%E6%95%B0%E3%82%92%E6%95%B0%E3%81%88%E3%82%8B%E3%81%AE%E3%81%8C%E3%83%A9%E3%82%A4%E3%82%BF%E3%83%BC%E3%82%92%E8%8B%A6%E3%81%97%E3%82%81%E3%82%8B%E7%90%86%E7%94%B1%E3%81%A8%E3%81%9D%E3%81%AE%E8%A7%A3%E6%B1%BA%E6%B3%95-08-22" rel="noopener noreferrer"&gt;なぜ日本語の文字数を数えることは作家にとって悪夢なのか ― その対処法&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Kanji (漢字)&lt;/li&gt;
&lt;li&gt;Hiragana (ひらがな)&lt;/li&gt;
&lt;li&gt;Katakana (カタカナ)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Hiragana What Writers Need
&lt;/h3&gt;

&lt;p&gt;Hiragana has 46 basic sounds. It writes native Japanese words and grammar bits like particles, so a line such as すみません for sumimasen lands fully in hiragana. When you count length, those marks are real units, not decoration. Skip them and your total underreports what a reader actually sees on the page.&lt;/p&gt;

&lt;h3&gt;
  
  
  Kanji What Writers Need
&lt;/h3&gt;

&lt;p&gt;Lead with meaning, not sound: 山 means mountain before you stress yama or san. Kanji came from China and carry both sense and reading, so 火山 is fire plus mountain and reads as volcano, often kazan when the s voices to z. Treat each kanji as a meaning unit when you count. That habit keeps compounds from getting sliced into fake “letters” by tools built for English only.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Scripts Sit on One Page
&lt;/h2&gt;

&lt;p&gt;Mixed scripts break naive character counters the moment layout changes. School pages often go horizontal left to right, which feels familiar if you write English. Novels and harder material often go vertical, starting top-right and moving down each column toward the left edge. A counter that ignores columns will skip text or pad blanks. Always match the real reading path before you trust a number.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Romaji Sabotages Length Checks
&lt;/h2&gt;

&lt;p&gt;Counting romaji is not counting Japanese. Writing yama for 山 or やま is romanization, and it sabotages length work because Latin letters don’t match script density or line breaks. Drop romaji after day one of study. Draft and count in real kana and kanji so your totals match what editors, teachers, and on-page tools actually measure.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Fast Can You Learn Kana?
&lt;/h2&gt;

&lt;p&gt;Hiragana and katakana take roughly 2, 5 days with charts, flashcards, and simple apps. That speed matters when a deadline needs a clean character total, not a romanized guess. Katakana often looks like a stiffer version of hiragana, which helps once you’ve seen both charts side by side. Finish the sets early and your counts stop lying.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Many Kanji Actually Matter?
&lt;/h2&gt;

&lt;p&gt;About 2,000 kanji are the school target by the end of junior high. That set supports university entry, JLPT prep, books, magazines, manga, and textbooks. Some forms use 1, 3 strokes and some push past 20, and 山 is a clear pictograph of a mountain. Focus on that common pool first if you need stable length stats on real pages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Meaning First Then Sound
&lt;/h2&gt;

&lt;p&gt;Prioritize meaning, and learn the sound with it. Know that 山 is mountain before you fixate on readings, then compounds like 火山 become guessable as volcano and often ka-zan when s turns to z. Writers who count this way stop splitting kanji into empty strokes. The number finally reflects sense units a Japanese reader would accept.&lt;/p&gt;

&lt;h2&gt;
  
  
  When You Can Skip Kanji
&lt;/h2&gt;

&lt;p&gt;Short-trip speakers who only need conversation can wait on kanji. Long-haul readers, manga fans, job seekers, and anyone who must handle on-screen text should start now even when it feels impossible. Speech skill alone won’t fix a character count on mixed pages. Pick the path that matches how long you’ll actually use the language.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Practical Fix for Writers
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Master both kana sets before you care about polished length stats.&lt;/li&gt;
&lt;li&gt;Stop drafting in romaji so every glyph you type is real script.&lt;/li&gt;
&lt;li&gt;Count only in hiragana, katakana, and kanji on the finished line.&lt;/li&gt;
&lt;li&gt;Treat each kanji as a meaning unit, not a stack of Latin letters.&lt;/li&gt;
&lt;li&gt;Use charts and flashcards when a form stalls you, then recount the line.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Mistakes That Break Your Count
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Treating every glyph like an English letter&lt;/li&gt;
&lt;li&gt;Mixing romaji into drafts you plan to measure&lt;/li&gt;
&lt;li&gt;Ignoring vertical column layout on novels and hard text&lt;/li&gt;
&lt;li&gt;Skipping kana and jumping straight to guesswork&lt;/li&gt;
&lt;li&gt;Assuming strong speech means strong kanji skill&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Fix those and your totals stop swinging for no good reason.&lt;/p&gt;

&lt;h3&gt;
  
  
  Should I Write in Romaji?
&lt;/h3&gt;

&lt;p&gt;No. Romaji study sabotages progress on real length and reading. Learn hiragana and katakana within a few days instead, then draft and count only in actual script.&lt;/p&gt;

&lt;p&gt;Writers who need a clean total on mixed lines can run a quick pass on &lt;a href="https://mojisuu-count.com/" rel="noopener noreferrer"&gt;mojisuu-count.com&lt;/a&gt; after the kana sets stick, then keep building kanji without guessing at Latin stand-ins.&lt;/p&gt;

</description>
      <category>writing</category>
      <category>learning</category>
    </item>
  </channel>
</rss>
