diff --git a/src/components/LoadingScreen/LoadingScreen.tsx b/src/components/LoadingScreen/LoadingScreen.tsx index ae23f62..be07ad6 100644 --- a/src/components/LoadingScreen/LoadingScreen.tsx +++ b/src/components/LoadingScreen/LoadingScreen.tsx @@ -7,7 +7,7 @@ interface Props { } const BOOT_LINES = [ - { ts: '0.0001', msg: 'Initializing RahulOS...' }, + { ts: '0.0001', msg: 'Initializing Rahul AP...' }, { ts: '0.0042', msg: 'Loading kernel...' }, { ts: '0.0125', msg: 'Loading React...' }, { ts: '0.0210', msg: 'Loading portfolio...' }, @@ -74,7 +74,7 @@ const LoadingScreen: React.FC = ({ onComplete }) => { >
- RAHUL_OS_V2.0 + RAHUL_AP_V2.0
diff --git a/src/components/Terminal/Terminal.scss b/src/components/Terminal/Terminal.scss index 852fae9..2b8464d 100644 --- a/src/components/Terminal/Terminal.scss +++ b/src/components/Terminal/Terminal.scss @@ -8,12 +8,12 @@ color: var(--fg); font-family: var(--font-mono); cursor: text; - overflow: hidden; + overflow-y: auto; + overflow-x: hidden; } .terminal-scroll { - height: 100%; - overflow-y: auto; + min-height: 100%; padding: clamp(16px, 4vw, 40px); max-width: 900px; margin: 0 auto; @@ -23,10 +23,15 @@ .terminal-welcome { margin-bottom: 16px; - color: var(--primary); - p:first-child { - font-weight: 700; + > * + * { + margin-top: 8px; + } + + .welcome-login { + p + p { + margin-top: 0; + } } } @@ -92,6 +97,20 @@ margin-top: 4px; } +.out-help-section { + margin-bottom: 14px; +} + +.out-section-title { + color: var(--accent); + text-transform: uppercase; + letter-spacing: 2px; + font-size: 0.72rem; + padding-bottom: 4px; + margin-bottom: 6px; + border-bottom: 1px dashed var(--border-color); +} + .out-help .out-row { display: flex; gap: 16px; @@ -121,6 +140,19 @@ padding-left: 8px; } +.out-neofetch { + display: flex; + gap: 24px; + flex-wrap: wrap; + + .out-ascii { + color: var(--terminal-green); + font-family: inherit; + line-height: 1.3; + white-space: pre; + } +} + .terminal-suggestions { display: flex; flex-wrap: wrap; diff --git a/src/components/Terminal/Terminal.tsx b/src/components/Terminal/Terminal.tsx index 25bcbd5..bbeba17 100644 --- a/src/components/Terminal/Terminal.tsx +++ b/src/components/Terminal/Terminal.tsx @@ -1,6 +1,6 @@ import React, { useCallback, useEffect, useRef, useState } from 'react'; import { useTheme, Theme } from '../../context/ThemeContext'; -import { runCommand, COMMAND_NAMES, CommandOutput } from './commands'; +import { runCommand, COMMAND_NAMES, OPEN_TARGETS, CommandOutput } from './commands'; import './Terminal.scss'; interface LineEntry { @@ -10,10 +10,35 @@ interface LineEntry { } const THEME_ORDER: Theme[] = ['dark', 'neon', 'pastel', 'light']; -const WELCOME = 'Type "help" to begin.'; +const PROMPT = 'guest@rahulap:~$'; let idCounter = 0; +type CompletionContext = { kind: 'command' | 'open-arg'; prefix: string; options: string[] }; + +const getCompletionContext = (value: string): CompletionContext | null => { + const trailingSpace = /\s$/.test(value); + const parts = value.split(/\s+/).filter(Boolean); + if (parts.length === 0) return null; + + const first = parts[0].toLowerCase(); + if (first === 'open' && (parts.length > 1 || trailingSpace)) { + return { kind: 'open-arg', prefix: parts.length > 1 ? parts[1].toLowerCase() : '', options: OPEN_TARGETS }; + } + if (parts.length > 1) return null; + return { kind: 'command', prefix: first, options: COMMAND_NAMES }; +}; + +const formatLastLogin = () => { + const parts = new Intl.DateTimeFormat('en-US', { + month: 'short', day: '2-digit', year: 'numeric', + hour: '2-digit', minute: '2-digit', hour12: false, + timeZone: 'Asia/Kolkata', + }).formatToParts(new Date()); + const get = (type: string) => parts.find(p => p.type === type)?.value; + return `${get('month')} ${get('day')} ${get('year')} ${get('hour')}:${get('minute')} IST`; +}; + const Terminal: React.FC = () => { const { theme, setTheme } = useTheme(); const [lines, setLines] = useState([]); @@ -22,6 +47,7 @@ const Terminal: React.FC = () => { const [historyIndex, setHistoryIndex] = useState(null); const [matrixActive, setMatrixActive] = useState(false); + const [lastLogin] = useState(formatLastLogin); const inputRef = useRef(null); const bottomRef = useRef(null); @@ -97,17 +123,18 @@ const Terminal: React.FC = () => { if (e.key === 'Tab') { e.preventDefault(); - const [prefix] = input.split(/\s+/); - if (!prefix) return; - const matches = COMMAND_NAMES.filter(c => c.startsWith(prefix.toLowerCase())); + const ctx = getCompletionContext(input); + if (!ctx) return; + const matches = ctx.options.filter(o => o.startsWith(ctx.prefix)); if (matches.length === 1) { - setInput(matches[0] + ' '); + setInput(ctx.kind === 'open-arg' ? `open ${matches[0]} ` : `${matches[0]} `); } } }; - const suggestions = input.trim() - ? COMMAND_NAMES.filter(c => c.startsWith(input.trim().toLowerCase()) && c !== input.trim().toLowerCase()) + const completionCtx = getCompletionContext(input); + const suggestions = completionCtx + ? completionCtx.options.filter(o => o.startsWith(completionCtx.prefix) && o !== completionCtx.prefix) : []; return ( @@ -116,14 +143,18 @@ const Terminal: React.FC = () => {
-

RahulOS v2.0 — interactive portfolio

-

{WELCOME}

+

Rahul AP v2.1

+
+

Last login:

+

{lastLogin}

+
+

Type "help" to begin.

{lines.map(line => (
- visitor@rahul:~$ + {PROMPT} {line.command}
{line.output &&
{line.output}
} @@ -131,7 +162,7 @@ const Terminal: React.FC = () => { ))}
- visitor@rahul:~$ + {PROMPT} CommandOutput; +type Category = 'Navigation' | 'Resources' | 'Terminal'; + interface CommandDef { name: string; description: string; + category?: Category; + hidden?: boolean; handler: CommandHandler; } +const CATEGORY_ORDER: Category[] = ['Navigation', 'Resources', 'Terminal']; + const slug = (title: string) => title.toLowerCase().replace(/\s+/g, '_'); const openUrl = (url?: string) => { if (url) window.open(url, '_blank', 'noopener,noreferrer'); }; +export const OPEN_TARGETS: string[] = [ + ...resumeData.projects.map(p => slug(p.title)), + 'github', + 'linkedin', +]; + const resolveProjectUrl = (arg: string): { url?: string; title?: string } => { const byIndex = resumeData.projects[Number(arg) - 1]; if (byIndex) return { url: byIndex.link ?? byIndex.github, title: byIndex.title }; @@ -32,34 +45,89 @@ const resolveProjectUrl = (arg: string): { url?: string; title?: string } => { return {}; }; +const OpeningLink: React.FC<{ label: string; url?: string }> = ({ label, url }) => { + const [redirecting, setRedirecting] = React.useState(false); + + React.useEffect(() => { + const timer = setTimeout(() => { + setRedirecting(true); + openUrl(url); + }, 260); + return () => clearTimeout(timer); + }, [url]); + + return React.createElement('div', { className: 'out-block' }, + React.createElement('p', null, `Opening ${label}...`), + redirecting && React.createElement('p', { className: 'out-muted' }, 'Redirecting...') + ); +}; + +const opening = (label: string, url?: string) => React.createElement(OpeningLink, { label, url }); + +const aboutOutput = () => + React.createElement('div', { className: 'out-block' }, + React.createElement('p', null, `Hi! I'm ${resumeData.name}.`), + React.createElement('p', null, resumeData.hero.bio), + React.createElement('p', { className: 'out-muted' }, `Location: ${resumeData.location}`) + ); + +const contactOutput = () => + React.createElement('div', { className: 'out-block' }, + React.createElement('p', null, `Email: ${resumeData.contact.email}`), + React.createElement('p', null, `Phone: ${resumeData.contact.phone}`), + React.createElement('p', null, `LinkedIn: ${resumeData.contact.linkedin}`), + React.createElement('p', null, `GitHub: ${resumeData.contact.github}`), + React.createElement('p', { className: 'out-hint' }, 'Type: open github | open linkedin') + ); + +const VIRTUAL_FILES: Record CommandOutput> = { + 'about.md': aboutOutput, + 'contact.md': contactOutput, + 'resume.pdf': () => opening('resume', resumeData.contact.cv), +}; + +const LS_ENTRIES = ['about.md', 'projects/', 'experience/', 'resume.pdf', 'contact.md', 'blog/']; + +const resolveVirtualFile = (name: string): (() => CommandOutput) | undefined => { + if (VIRTUAL_FILES[name]) return VIRTUAL_FILES[name]; + const basenameMatch = Object.keys(VIRTUAL_FILES).find(k => k.replace(/\.[^.]+$/, '') === name); + return basenameMatch ? VIRTUAL_FILES[basenameMatch] : undefined; +}; + +const SudoHire: React.FC = () => { + const [stage, setStage] = React.useState(0); + + React.useEffect(() => { + const timers = [ + setTimeout(() => setStage(1), 400), + setTimeout(() => setStage(2), 900), + setTimeout(() => setStage(3), 1300), + ]; + return () => timers.forEach(clearTimeout); + }, []); + + return React.createElement('div', { className: 'out-block' }, + React.createElement('p', null, '[sudo] password for recruiter:'), + stage >= 1 && React.createElement('p', null, '********'), + stage >= 2 && React.createElement('p', { className: 'out-title' }, 'Access Granted.'), + stage >= 3 && React.createElement('div', { className: 'out-block' }, + React.createElement('p', null, 'Opening contact information...'), + contactOutput() + ) + ); +}; + export const COMMANDS: CommandDef[] = [ - { - name: 'help', - description: 'Show commands', - handler: () => - React.createElement('div', { className: 'out-help' }, - React.createElement('p', { className: 'out-title' }, 'Available Commands'), - COMMANDS.map(c => - React.createElement('div', { className: 'out-row', key: c.name }, - React.createElement('span', { className: 'out-cmd' }, c.name), - React.createElement('span', { className: 'out-desc' }, c.description) - ) - ) - ), - }, { name: 'about', description: 'About me', - handler: () => - React.createElement('div', { className: 'out-block' }, - React.createElement('p', null, `Hi! I'm ${resumeData.name}.`), - React.createElement('p', null, resumeData.hero.bio), - React.createElement('p', { className: 'out-muted' }, `Location: ${resumeData.location}`) - ), + category: 'Navigation', + handler: aboutOutput, }, { name: 'skills', description: 'Technologies', + category: 'Navigation', handler: () => React.createElement('div', { className: 'out-block' }, Object.entries(resumeData.skills).map(([category, items]) => @@ -75,6 +143,7 @@ export const COMMANDS: CommandDef[] = [ { name: 'projects', description: 'Featured projects', + category: 'Navigation', handler: () => React.createElement('div', { className: 'out-block' }, resumeData.projects.map((p, i) => @@ -87,23 +156,10 @@ export const COMMANDS: CommandDef[] = [ React.createElement('p', { className: 'out-hint' }, 'Type: open e.g. open 1') ), }, - { - name: 'open', - description: 'Open a project, github or linkedin', - handler: (args) => { - const target = args[0]; - if (!target) return React.createElement('p', { className: 'out-error' }, 'Usage: open '); - if (target === 'github') { openUrl(resumeData.contact.github); return React.createElement('p', null, 'Opening GitHub...'); } - if (target === 'linkedin') { openUrl(resumeData.contact.linkedin); return React.createElement('p', null, 'Opening LinkedIn...'); } - const { url, title } = resolveProjectUrl(target); - if (!url) return React.createElement('p', { className: 'out-error' }, `No project found for "${target}"`); - openUrl(url); - return React.createElement('p', null, `Opening ${title}...`); - }, - }, { name: 'experience', description: 'Work experience', + category: 'Navigation', handler: () => React.createElement('div', { className: 'out-block' }, resumeData.experience.map((exp, i) => @@ -120,36 +176,67 @@ export const COMMANDS: CommandDef[] = [ { name: 'resume', description: 'Download resume', - handler: () => { - openUrl(resumeData.contact.cv); - return React.createElement('p', null, 'Opening resume...'); - }, - }, - { - name: 'contact', - description: 'Contact information', - handler: () => - React.createElement('div', { className: 'out-block' }, - React.createElement('p', null, `Email: ${resumeData.contact.email}`), - React.createElement('p', null, `Phone: ${resumeData.contact.phone}`), - React.createElement('p', null, `LinkedIn: ${resumeData.contact.linkedin}`), - React.createElement('p', null, `GitHub: ${resumeData.contact.github}`), - React.createElement('p', { className: 'out-hint' }, 'Type: open github | open linkedin') - ), + category: 'Resources', + handler: () => opening('resume', resumeData.contact.cv), }, { name: 'github', description: 'Open GitHub', - handler: () => { openUrl(resumeData.contact.github); return React.createElement('p', null, 'Opening GitHub...'); }, + category: 'Resources', + handler: () => opening('GitHub', resumeData.contact.github), }, { name: 'linkedin', description: 'Open LinkedIn', - handler: () => { openUrl(resumeData.contact.linkedin); return React.createElement('p', null, 'Opening LinkedIn...'); }, + category: 'Resources', + handler: () => opening('LinkedIn', resumeData.contact.linkedin), + }, + { + name: 'contact', + description: 'Contact information', + category: 'Resources', + handler: contactOutput, + }, + { + name: 'open', + description: 'Open a project, github or linkedin', + category: 'Resources', + handler: (args) => { + const target = args[0]; + if (!target) return React.createElement('p', { className: 'out-error' }, 'Usage: open '); + if (target === 'github') return opening('GitHub', resumeData.contact.github); + if (target === 'linkedin') return opening('LinkedIn', resumeData.contact.linkedin); + const { url, title } = resolveProjectUrl(target); + if (!url) return React.createElement('p', { className: 'out-error' }, `No project found for "${target}"`); + return opening(title ?? target, url); + }, + }, + { + name: 'help', + description: 'Show commands', + category: 'Terminal', + handler: () => + React.createElement('div', { className: 'out-help' }, + React.createElement('p', { className: 'out-title' }, 'Available Commands'), + CATEGORY_ORDER.map(category => { + const cmds = COMMANDS.filter(c => !c.hidden && c.category === category); + if (!cmds.length) return null; + return React.createElement('div', { className: 'out-help-section', key: category }, + React.createElement('p', { className: 'out-section-title' }, category), + cmds.map(c => + React.createElement('div', { className: 'out-row', key: c.name }, + React.createElement('span', { className: 'out-cmd' }, c.name), + React.createElement('span', { className: 'out-desc' }, c.description) + ) + ) + ); + }) + ), }, { name: 'theme', description: 'Change terminal theme', + category: 'Terminal', handler: (_args, ctx) => { ctx.cycleTheme(); return React.createElement('p', null, 'Switching theme...'); @@ -158,26 +245,106 @@ export const COMMANDS: CommandDef[] = [ { name: 'clear', description: 'Clear terminal', + category: 'Terminal', handler: (_args, ctx) => { ctx.clear(); return null; }, }, { name: 'whoami', description: 'Hidden command', - handler: () => React.createElement('p', null, 'visitor // curious human probably scouting for a hire'), + hidden: true, + handler: () => React.createElement('p', null, 'guest // curious human probably scouting for a hire'), }, { name: 'coffee', description: 'Hidden command', + hidden: true, handler: () => React.createElement('p', null, '☕ brewing... here you go.'), }, { name: 'matrix', description: 'Hidden command', + hidden: true, handler: (_args, ctx) => { ctx.triggerMatrix(); return React.createElement('p', null, 'Wake up, Neo...'); }, }, + { + name: 'exit', + description: 'Hidden command', + hidden: true, + handler: () => + React.createElement('div', { className: 'out-block' }, + React.createElement('p', null, 'Nice try.'), + React.createElement('p', null, "This portfolio isn't going anywhere 😄") + ), + }, + { + name: 'fortune', + description: 'Hidden command', + hidden: true, + handler: () => { + const pick = FORTUNES[Math.floor(Math.random() * FORTUNES.length)]; + return React.createElement('div', { className: 'out-block' }, + React.createElement('p', null, 'Random developer quote:'), + React.createElement('p', { className: 'out-title' }, `"${pick.quote}"`), + React.createElement('p', { className: 'out-muted' }, `— ${pick.author}`) + ); + }, + }, + { + name: 'ls', + description: 'Hidden command', + hidden: true, + handler: () => + React.createElement('div', { className: 'out-block' }, + LS_ENTRIES.map(entry => React.createElement('p', { key: entry }, entry)) + ), + }, + { + name: 'cat', + description: 'Hidden command', + hidden: true, + handler: (args) => { + const file = args[0]; + if (!file) return React.createElement('p', { className: 'out-error' }, 'Usage: cat '); + const contentFn = resolveVirtualFile(file); + if (!contentFn) return React.createElement('p', { className: 'out-error' }, `cat: ${file}: No such file or directory`); + return contentFn(); + }, + }, + { + name: 'pwd', + description: 'Hidden command', + hidden: true, + handler: () => React.createElement('p', null, '/home/rahul'), + }, + { + name: 'neofetch', + description: 'Hidden command', + hidden: true, + handler: () => + React.createElement('div', { className: 'out-neofetch' }, + React.createElement('pre', { className: 'out-ascii' }, + ' #####\n ###########\n ###### ######\n #### ####' + ), + React.createElement('div', { className: 'out-block' }, + React.createElement('p', { className: 'out-title' }, 'Rahul AP v2.1'), + React.createElement('p', null, `Role: ${resumeData.experience[0].role}`), + React.createElement('p', null, `Experience: ${resumeData.hero.exp}+ Years`), + React.createElement('p', null, `Frontend: ${resumeData.skills.frontend.slice(0, 3).join(', ')}`), + React.createElement('p', null, `Backend: ${resumeData.skills.backend.slice(0, 3).join(', ')}`), + React.createElement('p', null, `AI: ${resumeData.skills.ai.slice(0, 3).join(', ')}`), + React.createElement('p', null, `Location: ${resumeData.location}`) + ) + ), + }, + { + name: 'blog', + description: 'Hidden command', + hidden: true, + handler: () => React.createElement('p', { className: 'out-muted' }, 'blog: under construction — check back soon.'), + }, ]; export function runCommand(input: string, ctx: CommandContext): CommandOutput { @@ -185,11 +352,13 @@ export function runCommand(input: string, ctx: CommandContext): CommandOutput { if (!name) return null; if (name === 'sudo' && args.join(' ') === 'hire rahul') { - return React.createElement('p', { className: 'out-title' }, 'Permission granted. Excellent choice.'); + return React.createElement(SudoHire); } const cmd = COMMANDS.find(c => c.name === name.toLowerCase()); if (!cmd) { + const fileFn = resolveVirtualFile(name.toLowerCase()); + if (fileFn) return fileFn(); return React.createElement('p', { className: 'out-error' }, `command not found: ${name}. Type "help" for a list of commands.`); } diff --git a/src/data/fortunes.ts b/src/data/fortunes.ts new file mode 100644 index 0000000..6625a3d --- /dev/null +++ b/src/data/fortunes.ts @@ -0,0 +1,117 @@ +export interface Fortune { + quote: string; + author: string; +} + +export const FORTUNES: Fortune[] = [ + { quote: 'Programs must be written for people to read.', author: 'Harold Abelson' }, + { quote: 'Simplicity is prerequisite for reliability.', author: 'Edsger W. Dijkstra' }, + { quote: 'First, solve the problem. Then, write the code.', author: 'John Johnson' }, + { quote: 'Talk is cheap. Show me the code.', author: 'Linus Torvalds' }, + { quote: 'Make it work, make it right, make it fast.', author: 'Kent Beck' }, + { quote: 'Any fool can write code that a computer can understand. Good programmers write code that humans can understand.', author: 'Martin Fowler' }, + { quote: 'The best error message is the one that never shows up.', author: 'Thomas Fuchs' }, + { quote: 'Code is like humor. When you have to explain it, it’s bad.', author: 'Cory House' }, + { quote: 'Simplicity is the soul of efficiency.', author: 'Austin Freeman' }, + { quote: 'Before software can be reusable it first has to be usable.', author: 'Ralph Johnson' }, + { quote: 'Make it work, make it right, make it fast.', author: 'Kent Beck' }, + { quote: 'The most disastrous thing that you can ever learn is your first programming language.', author: 'Alan Kay' }, + { quote: 'Sometimes it pays to stay in bed on Monday, rather than spending the rest of the week debugging Monday’s code.', author: 'Dan Salomon' }, + { quote: 'Deleted code is debugged code.', author: 'Jeff Sickel' }, + { quote: 'It’s not a bug – it’s an undocumented feature.', author: 'Anonymous' }, + { quote: 'Walking on water and developing software from a specification are easy if both are frozen.', author: 'Edward V. Berard' }, + { quote: 'The trouble with programmers is that you can never tell what a programmer is doing until it’s too late.', author: 'Seymour Cray' }, + { quote: 'Optimism is an occupational hazard of programming; feedback is the treatment.', author: 'Kent Beck' }, + { quote: 'A good programmer is someone who always looks both ways before crossing a one-way street.', author: 'Doug Linder' }, + { quote: 'There are only two hard things in Computer Science: cache invalidation and naming things.', author: 'Phil Karlton' }, + { quote: 'Programming isn’t about what you know; it’s about what you can figure out.', author: 'Chris Pine' }, + { quote: 'The computer was born to solve problems that did not exist before.', author: 'Bill Gates' }, + { quote: 'Software is a great combination between artistry and engineering.', author: 'Bill Gates' }, + { quote: 'Testing leads to failure, and failure leads to understanding.', author: 'Burt Rutan' }, + { quote: 'Debugging is twice as hard as writing the code in the first place.', author: 'Brian Kernighan' }, + { quote: 'If debugging is the process of removing bugs, then programming must be the process of putting them in.', author: 'Edsger W. Dijkstra' }, + { quote: 'Premature optimization is the root of all evil.', author: 'Donald Knuth' }, + { quote: 'A language that doesn’t affect the way you think about programming is not worth knowing.', author: 'Alan Perlis' }, + { quote: 'Controlling complexity is the essence of computer programming.', author: 'Brian Kernighan' }, + { quote: 'The function of good software is to make the complex appear simple.', author: 'Grady Booch' }, + { quote: 'Good code is its own best documentation.', author: 'Steve McConnell' }, + { quote: 'Truth can only be found in one place: the code.', author: 'Robert C. Martin' }, + { quote: 'Clean code always looks like it was written by someone who cares.', author: 'Robert C. Martin' }, + { quote: 'First, solve the problem. Then, write the code.', author: 'John Johnson' }, + { quote: 'Experience is the name everyone gives to their mistakes.', author: 'Oscar Wilde' }, + { quote: 'In order to be irreplaceable, one must always be different.', author: 'Coco Chanel' }, + { quote: 'Java is to JavaScript what car is to Carpet.', author: 'Chris Heilmann' }, + { quote: 'Knowledge is power.', author: 'Francis Bacon' }, + { quote: 'Sometimes the elegant implementation is just a function. Not a method. Not a class. Not a framework. Just a function.', author: 'John Carmack' }, + { quote: 'Perfection is achieved not when there is nothing more to add, but when there is nothing left to take away.', author: 'Antoine de Saint-Exupéry' }, + { quote: 'Ninety percent of everything is crap.', author: 'Theodore Sturgeon' }, + { quote: 'Programs must be written for people to read, and only incidentally for machines to execute.', author: 'Harold Abelson' }, + { quote: 'Any application that can be written in JavaScript, will eventually be written in JavaScript.', author: 'Jeff Atwood' }, + { quote: 'One of the best programming skills you can have is knowing when to walk away for a while.', author: 'Oscar Godson' }, + { quote: 'Good code is short, simple, and symmetrical — the challenge is figuring out how to get there.', author: 'Sandi Metz' }, + { quote: 'Programming is the art of telling another human being what one wants the computer to do.', author: 'Donald Knuth' }, + { quote: 'The only way to learn a new programming language is by writing programs in it.', author: 'Dennis Ritchie' }, + { quote: 'The most important property of a program is whether it accomplishes the intention of its user.', author: 'C.A.R. Hoare' }, + { quote: 'Programming can be fun, so can cryptography; however they should not be combined.', author: 'Kreitzberg and Shneiderman' }, + { quote: 'Not all those who wander are lost, but they should probably check the console.', author: 'Anonymous' }, + { quote: 'It works on my machine.', author: 'Every developer, ever' }, + { quote: 'There is nothing more permanent than a temporary hack.', author: 'Kyle Simpson' }, + { quote: 'Move fast and fix things.', author: 'Anonymous' }, + { quote: 'A ship in port is safe, but that is not what ships are built for.', author: 'Grace Hopper' }, + { quote: 'The most efficient debugging tool is still careful thought, coupled with judiciously placed print statements.', author: 'Brian Kernighan' }, + { quote: 'Weeks of coding can save you hours of planning.', author: 'Anonymous' }, + { quote: 'It’s hard enough to find an error in your code when you’re looking for it; it’s even harder when you’ve assumed your code is error-free.', author: 'Steve McConnell' }, + { quote: 'Measuring programming progress by lines of code is like measuring aircraft building progress by weight.', author: 'Bill Gates' }, + { quote: 'The best code is no code at all.', author: 'Jeff Atwood' }, + { quote: 'Simplicity is prerequisite for reliability.', author: 'Edsger W. Dijkstra' }, + { quote: 'The cheapest, fastest, and most reliable components are those that aren’t there.', author: 'Gordon Bell' }, + { quote: 'Programs are meant to be read by humans and only incidentally for computers to execute.', author: 'Donald Knuth' }, + { quote: 'There are two ways of constructing a software design: make it so simple that there are obviously no deficiencies, or make it so complicated that there are no obvious deficiencies.', author: 'C.A.R. Hoare' }, + { quote: 'Talk is cheap. Show me the code.', author: 'Linus Torvalds' }, + { quote: 'The computer is incredibly fast, accurate, and stupid. Man is unbelievably slow, inaccurate, and brilliant. Together they are powerful beyond imagination.', author: 'Albert Einstein' }, + { quote: 'Beware of bugs in the above code; I have only proved it correct, not tried it.', author: 'Donald Knuth' }, + { quote: 'Every great developer you know got there by solving problems they were unqualified to solve until they actually did it.', author: 'Patrick McKenzie' }, + { quote: 'Good design adds value faster than it adds cost.', author: 'Thomas C. Gale' }, + { quote: 'The best way to predict the future is to implement it.', author: 'David Heinemeier Hansson' }, + { quote: 'A computer once beat me at chess, but it was no match for me at kick boxing.', author: 'Emo Philips' }, + { quote: 'The function of good software is to make the complex appear simple.', author: 'Grady Booch' }, + { quote: 'Simplicity and elegance are unpopular because they require hard work and discipline to achieve.', author: 'Edsger W. Dijkstra' }, + { quote: 'Learning to write programs stretches your mind, and helps you think better.', author: 'Bill Gates' }, + { quote: 'If you don’t like testing your product, most likely your customers won’t like to test it either.', author: 'Anonymous' }, + { quote: 'One man’s crappy software is another man’s full time job.', author: 'Jessica Gaston' }, + { quote: 'Software undergoes beta testing shortly before it’s released. Beta is Latin for “still doesn’t work.”', author: 'Anonymous' }, + { quote: 'The trouble with programmers is that you can never tell what a programmer is doing until it’s too late.', author: 'Seymour Cray' }, + { quote: 'When debugging, novices insert corrective code; experts remove defective code.', author: 'Richard Pattis' }, + { quote: 'Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning.', author: 'Rick Cook' }, + { quote: 'The only way to go fast is to go well.', author: 'Robert C. Martin' }, + { quote: 'Code never lies, comments sometimes do.', author: 'Ron Jeffries' }, + { quote: 'A user interface is like a joke. If you have to explain it, it’s not that good.', author: 'Anonymous' }, + { quote: 'To iterate is human, to recurse divine.', author: 'L. Peter Deutsch' }, + { quote: 'There’s no place like 127.0.0.1.', author: 'Anonymous' }, + { quote: 'Real programmers count from 0.', author: 'Anonymous' }, + { quote: 'It’s not a bug, it’s a feature.', author: 'Anonymous' }, + { quote: 'The best thing about a boolean is even if you are wrong, you are only off by a bit.', author: 'Anonymous' }, + { quote: 'A SQL query walks into a bar, walks up to two tables and asks, “Can I join you?”', author: 'Anonymous' }, + { quote: 'Why do programmers prefer dark mode? Because light attracts bugs.', author: 'Anonymous' }, + { quote: 'There are only 10 types of people in the world: those who understand binary, and those who don’t.', author: 'Anonymous' }, + { quote: 'I would love to change the world, but they won’t give me the source code.', author: 'Anonymous' }, + { quote: 'To err is human, but to really foul things up you need a computer.', author: 'Paul Ehrlich' }, + { quote: 'A computer will do what you tell it to do, but that may be much different from what you had in mind.', author: 'Joseph Weizenbaum' }, + { quote: 'The question of whether a computer can think is no more interesting than the question of whether a submarine can swim.', author: 'Edsger W. Dijkstra' }, + { quote: 'Computer science is no more about computers than astronomy is about telescopes.', author: 'Edsger W. Dijkstra' }, + { quote: 'The competent programmer is fully aware of the strictly limited size of his own skull.', author: 'Edsger W. Dijkstra' }, + { quote: 'If you can’t explain it simply, you don’t understand it well enough.', author: 'Albert Einstein' }, + { quote: 'The advance of technology is based on making it fit in so that you don’t really even notice it, so it’s part of everyday life.', author: 'Bill Gates' }, + { quote: 'Never trust a computer you can’t throw out a window.', author: 'Steve Wozniak' }, + { quote: 'That’s the thing about people who think they hate computers. What they really hate is lousy programmers.', author: 'Larry Niven' }, + { quote: 'It is practically impossible to teach good programming to students that have had prior exposure to BASIC.', author: 'Edsger W. Dijkstra' }, + { quote: 'The trouble with the world is that the stupid are cocksure and the intelligent are full of doubt.', author: 'Bertrand Russell' }, + { quote: 'What one programmer can do in one month, two programmers can do in two months.', author: 'Frederick P. Brooks Jr.' }, + { quote: 'Adding manpower to a late software project makes it later.', author: 'Frederick P. Brooks Jr.' }, + { quote: 'Documentation is a love letter that you write to your future self.', author: 'Damian Conway' }, + { quote: 'Design and programming are human activities; forget that and all is lost.', author: 'Bjarne Stroustrup' }, + { quote: 'C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off.', author: 'Bjarne Stroustrup' }, + { quote: 'There are two ways to write error-free programs; only the third one works.', author: 'Alan J. Perlis' }, + { quote: 'Fools ignore complexity. Pragmatists suffer it. Some can avoid it. Geniuses remove it.', author: 'Alan J. Perlis' }, + { quote: 'A program that produces incorrect results twice as fast is infinitely slower.', author: 'John Osterhout' }, +];