diff --git a/module-07-interactive-rebase/setup.ps1 b/module-07-interactive-rebase/setup.ps1 index 7228c40..ba73b0d 100644 --- a/module-07-interactive-rebase/setup.ps1 +++ b/module-07-interactive-rebase/setup.ps1 @@ -40,88 +40,78 @@ git commit -m "Initial commit" | Out-Null # Commit 1: WIP user profile $userProfile = @" -class UserProfile { - constructor(name, email) { - this.name = name; - this.email = email; - } -} +class UserProfile: + def __init__(self, name, email): + self.name = name + self.email = email "@ -Set-Content -Path "user-profile.js" -Value $userProfile -git add user-profile.js +Set-Content -Path "user_profile.py" -Value $userProfile +git add user_profile.py git commit -m "WIP: user profile" | Out-Null # Commit 2: Add validation (typo in message) $userProfileWithValidation = @" -class UserProfile { - constructor(name, email) { - this.name = name; - this.email = email; - } +class UserProfile: + def __init__(self, name, email): + self.name = name + self.email = email - validate() { - if (!this.name || !this.email) { - throw new Error('Name and email are required'); - } - return true; - } -} + def validate(self): + if not self.name or not self.email: + raise ValueError('Name and email are required') + return True "@ -Set-Content -Path "user-profile.js" -Value $userProfileWithValidation -git add user-profile.js +Set-Content -Path "user_profile.py" -Value $userProfileWithValidation +git add user_profile.py git commit -m "add validaton" | Out-Null # Intentional typo # Commit 3: Fix validation $userProfileFixed = @" -class UserProfile { - constructor(name, email) { - this.name = name; - this.email = email; - } +class UserProfile: + def __init__(self, name, email): + self.name = name + self.email = email - validate() { - if (!this.name || !this.email) { - throw new Error('Name and email are required'); - } - if (!this.email.includes('@')) { - throw new Error('Invalid email format'); - } - return true; - } -} + def validate(self): + if not self.name or not self.email: + raise ValueError('Name and email are required') + if '@' not in self.email: + raise ValueError('Invalid email format') + return True "@ -Set-Content -Path "user-profile.js" -Value $userProfileFixed -git add user-profile.js +Set-Content -Path "user_profile.py" -Value $userProfileFixed +git add user_profile.py git commit -m "fix validation bug" | Out-Null # Commit 4: Add tests (another WIP commit) $tests = @" -const assert = require('assert'); -const UserProfile = require('./user-profile'); +import unittest +from user_profile import UserProfile -describe('UserProfile', () => { - it('should validate correct user data', () => { - const user = new UserProfile('John', 'john@example.com'); - assert.strictEqual(user.validate(), true); - }); +class TestUserProfile(unittest.TestCase): + def test_validate_correct_user_data(self): + user = UserProfile('John', 'john@example.com') + self.assertTrue(user.validate()) - it('should reject missing name', () => { - const user = new UserProfile('', 'john@example.com'); - assert.throws(() => user.validate()); - }); + def test_reject_missing_name(self): + user = UserProfile('', 'john@example.com') + with self.assertRaises(ValueError): + user.validate() - it('should reject invalid email', () => { - const user = new UserProfile('John', 'invalid-email'); - assert.throws(() => user.validate()); - }); -}); + def test_reject_invalid_email(self): + user = UserProfile('John', 'invalid-email') + with self.assertRaises(ValueError): + user.validate() + +if __name__ == '__main__': + unittest.main() "@ -Set-Content -Path "user-profile.test.js" -Value $tests -git add user-profile.test.js +Set-Content -Path "test_user_profile.py" -Value $tests +git add test_user_profile.py git commit -m "WIP tests" | Out-Null # Return to module directory diff --git a/module-07-interactive-rebase/verify.ps1 b/module-07-interactive-rebase/verify.ps1 index 679f8ae..18ab563 100644 --- a/module-07-interactive-rebase/verify.ps1 +++ b/module-07-interactive-rebase/verify.ps1 @@ -86,70 +86,70 @@ if ($featureCommit.Length -lt 10) { } # Check that required files exist -if (-not (Test-Path "user-profile.js")) { - Write-Host "[FAIL] user-profile.js not found." -ForegroundColor Red +if (-not (Test-Path "user_profile.py")) { + Write-Host "[FAIL] user_profile.py not found." -ForegroundColor Red Set-Location .. exit 1 } -if (-not (Test-Path "user-profile.test.js")) { - Write-Host "[FAIL] user-profile.test.js not found." -ForegroundColor Red +if (-not (Test-Path "test_user_profile.py")) { + Write-Host "[FAIL] test_user_profile.py not found." -ForegroundColor Red Set-Location .. exit 1 } -# Check that user-profile.js contains all expected features -$userProfileContent = Get-Content "user-profile.js" -Raw +# Check that user_profile.py contains all expected features +$userProfileContent = Get-Content "user_profile.py" -Raw # Should have the class if ($userProfileContent -notmatch "class UserProfile") { - Write-Host "[FAIL] user-profile.js should contain UserProfile class." -ForegroundColor Red + Write-Host "[FAIL] user_profile.py should contain UserProfile class." -ForegroundColor Red Set-Location .. exit 1 } # Should have validation method -if ($userProfileContent -notmatch "validate\(\)") { - Write-Host "[FAIL] user-profile.js should contain validate() method." -ForegroundColor Red +if ($userProfileContent -notmatch "def validate\(") { + Write-Host "[FAIL] user_profile.py should contain validate() method." -ForegroundColor Red Set-Location .. exit 1 } # Should have email format validation (the final fix from commit 3) -if ($userProfileContent -notmatch "includes\('@'\)") { - Write-Host "[FAIL] user-profile.js should contain email format validation." -ForegroundColor Red +if ($userProfileContent -notmatch "'@'.*in.*email|email.*in.*'@'") { + Write-Host "[FAIL] user_profile.py should contain email format validation." -ForegroundColor Red Write-Host "Hint: Make sure all changes from all 4 commits are included." -ForegroundColor Yellow Set-Location .. exit 1 } # Check that test file has content -$testContent = Get-Content "user-profile.test.js" -Raw +$testContent = Get-Content "test_user_profile.py" -Raw -if ($testContent -notmatch "describe.*UserProfile") { - Write-Host "[FAIL] user-profile.test.js should contain UserProfile tests." -ForegroundColor Red +if ($testContent -notmatch "class.*TestUserProfile") { + Write-Host "[FAIL] test_user_profile.py should contain TestUserProfile tests." -ForegroundColor Red Set-Location .. exit 1 } # Check that we have at least 3 test cases -$testMatches = ([regex]::Matches($testContent, "it\(")).Count +$testMatches = ([regex]::Matches($testContent, "def test_")).Count if ($testMatches -lt 3) { - Write-Host "[FAIL] user-profile.test.js should contain at least 3 test cases." -ForegroundColor Red + Write-Host "[FAIL] test_user_profile.py should contain at least 3 test cases." -ForegroundColor Red Set-Location .. exit 1 } # Verify that the latest commit contains changes to both files $filesInLastCommit = git diff-tree --no-commit-id --name-only -r HEAD 2>$null -if ($filesInLastCommit -notcontains "user-profile.js") { - Write-Host "[FAIL] The feature commit should include user-profile.js" -ForegroundColor Red +if ($filesInLastCommit -notcontains "user_profile.py") { + Write-Host "[FAIL] The feature commit should include user_profile.py" -ForegroundColor Red Set-Location .. exit 1 } -if ($filesInLastCommit -notcontains "user-profile.test.js") { - Write-Host "[FAIL] The feature commit should include user-profile.test.js" -ForegroundColor Red +if ($filesInLastCommit -notcontains "test_user_profile.py") { + Write-Host "[FAIL] The feature commit should include test_user_profile.py" -ForegroundColor Red Set-Location .. exit 1 } diff --git a/module-08-cherry-pick/setup.ps1 b/module-08-cherry-pick/setup.ps1 index c44d5e8..879936f 100644 --- a/module-08-cherry-pick/setup.ps1 +++ b/module-08-cherry-pick/setup.ps1 @@ -28,21 +28,16 @@ git config user.email "user@workshop.local" | Out-Null # Create initial commits on main branch $app = @" -class App { - constructor() { - this.version = '1.0.0'; - } +class App: + def __init__(self): + self.version = '1.0.0' - start() { - console.log('App started'); - } -} - -module.exports = App; + def start(self): + print('App started') "@ -Set-Content -Path "app.js" -Value $app -git add app.js +Set-Content -Path "app.py" -Value $app +git add app.py git commit -m "Initial app implementation" | Out-Null $readme = @" @@ -60,132 +55,104 @@ git checkout -b development | Out-Null # Commit 1: Experimental feature (should NOT be cherry-picked) $appWithExperimental = @" -class App { - constructor() { - this.version = '1.0.0'; - this.experimentalMode = false; - } +class App: + def __init__(self): + self.version = '1.0.0' + self.experimental_mode = False - start() { - console.log('App started'); - if (this.experimentalMode) { - this.enableExperimentalFeatures(); - } - } + def start(self): + print('App started') + if self.experimental_mode: + self.enable_experimental_features() - enableExperimentalFeatures() { - console.log('Experimental features enabled'); - } -} - -module.exports = App; + def enable_experimental_features(self): + print('Experimental features enabled') "@ -Set-Content -Path "app.js" -Value $appWithExperimental -git add app.js +Set-Content -Path "app.py" -Value $appWithExperimental +git add app.py git commit -m "Add experimental AI features" | Out-Null # Commit 2: Security bug fix (SHOULD be cherry-picked) $security = @" -class Security { - static sanitizeInput(input) { - // Remove potential XSS attacks - return input.replace(/[<>]/g, ''); - } +import re - static validateToken(token) { - if (!token || token.length < 32) { - throw new Error('Invalid security token'); - } - return true; - } -} +class Security: + @staticmethod + def sanitize_input(input_str): + # Remove potential XSS attacks + return re.sub(r'[<>]', '', input_str) -module.exports = Security; + @staticmethod + def validate_token(token): + if not token or len(token) < 32: + raise ValueError('Invalid security token') + return True "@ -Set-Content -Path "security.js" -Value $security -git add security.js +Set-Content -Path "security.py" -Value $security +git add security.py git commit -m "Fix security vulnerability in input validation" | Out-Null # Commit 3: Another experimental feature (should NOT be cherry-picked) $appWithMoreExperimental = @" -class App { - constructor() { - this.version = '1.0.0'; - this.experimentalMode = false; - this.betaFeatures = []; - } +class App: + def __init__(self): + self.version = '1.0.0' + self.experimental_mode = False + self.beta_features = [] - start() { - console.log('App started'); - if (this.experimentalMode) { - this.enableExperimentalFeatures(); - } - } + def start(self): + print('App started') + if self.experimental_mode: + self.enable_experimental_features() - enableExperimentalFeatures() { - console.log('Experimental features enabled'); - } + def enable_experimental_features(self): + print('Experimental features enabled') - addBetaFeature(feature) { - this.betaFeatures.push(feature); - } -} - -module.exports = App; + def add_beta_feature(self, feature): + self.beta_features.append(feature) "@ -Set-Content -Path "app.js" -Value $appWithMoreExperimental -git add app.js +Set-Content -Path "app.py" -Value $appWithMoreExperimental +git add app.py git commit -m "Add beta features framework" | Out-Null # Commit 4: Performance bug fix (SHOULD be cherry-picked) $appWithPerformance = @" -class App { - constructor() { - this.version = '1.0.0'; - this.experimentalMode = false; - this.betaFeatures = []; - this.cache = new Map(); - } +class App: + def __init__(self): + self.version = '1.0.0' + self.experimental_mode = False + self.beta_features = [] + self.cache = {} - start() { - console.log('App started'); - if (this.experimentalMode) { - this.enableExperimentalFeatures(); - } - } + def start(self): + print('App started') + if self.experimental_mode: + self.enable_experimental_features() - enableExperimentalFeatures() { - console.log('Experimental features enabled'); - } + def enable_experimental_features(self): + print('Experimental features enabled') - addBetaFeature(feature) { - this.betaFeatures.push(feature); - } + def add_beta_feature(self, feature): + self.beta_features.append(feature) - getData(key) { - // Use cache to improve performance - if (this.cache.has(key)) { - return this.cache.get(key); - } - const data = this.fetchData(key); - this.cache.set(key, data); - return data; - } + def get_data(self, key): + # Use cache to improve performance + if key in self.cache: + return self.cache[key] + data = self.fetch_data(key) + self.cache[key] = data + return data - fetchData(key) { - // Simulate data fetching - return { key: key, value: 'data' }; - } -} - -module.exports = App; + def fetch_data(self, key): + # Simulate data fetching + return {'key': key, 'value': 'data'} "@ -Set-Content -Path "app.js" -Value $appWithPerformance -git add app.js +Set-Content -Path "app.py" -Value $appWithPerformance +git add app.py git commit -m "Fix performance issue with data caching" | Out-Null # Return to module directory diff --git a/module-08-cherry-pick/verify.ps1 b/module-08-cherry-pick/verify.ps1 index 94ebdc9..2512222 100644 --- a/module-08-cherry-pick/verify.ps1 +++ b/module-08-cherry-pick/verify.ps1 @@ -80,71 +80,71 @@ if ($mergeCommits) { exit 1 } -# Check that security.js exists (from the security fix commit) -if (-not (Test-Path "security.js")) { - Write-Host "[FAIL] security.js not found on main branch." -ForegroundColor Red +# Check that security.py exists (from the security fix commit) +if (-not (Test-Path "security.py")) { + Write-Host "[FAIL] security.py not found on main branch." -ForegroundColor Red Write-Host "Hint: You need to cherry-pick the 'Fix security vulnerability' commit" -ForegroundColor Yellow Set-Location .. exit 1 } -# Check that security.js has the security fix -$securityContent = Get-Content "security.js" -Raw +# Check that security.py has the security fix +$securityContent = Get-Content "security.py" -Raw -if ($securityContent -notmatch "sanitizeInput") { - Write-Host "[FAIL] security.js is missing the sanitizeInput function." -ForegroundColor Red +if ($securityContent -notmatch "sanitize_input") { + Write-Host "[FAIL] security.py is missing the sanitize_input function." -ForegroundColor Red Set-Location .. exit 1 } -if ($securityContent -notmatch "validateToken") { - Write-Host "[FAIL] security.js is missing the validateToken function." -ForegroundColor Red +if ($securityContent -notmatch "validate_token") { + Write-Host "[FAIL] security.py is missing the validate_token function." -ForegroundColor Red Set-Location .. exit 1 } -# Check that app.js exists -if (-not (Test-Path "app.js")) { - Write-Host "[FAIL] app.js not found." -ForegroundColor Red +# Check that app.py exists +if (-not (Test-Path "app.py")) { + Write-Host "[FAIL] app.py not found." -ForegroundColor Red Set-Location .. exit 1 } -# Check that app.js has the performance fix (cache) but NOT experimental features -$appContent = Get-Content "app.js" -Raw +# Check that app.py has the performance fix (cache) but NOT experimental features +$appContent = Get-Content "app.py" -Raw # Should have cache (from performance fix) if ($appContent -notmatch "cache") { - Write-Host "[FAIL] app.js is missing the performance fix (cache)." -ForegroundColor Red + Write-Host "[FAIL] app.py is missing the performance fix (cache)." -ForegroundColor Red Write-Host "Hint: You need to cherry-pick the 'Fix performance issue' commit" -ForegroundColor Yellow Set-Location .. exit 1 } -if ($appContent -notmatch "getData") { - Write-Host "[FAIL] app.js is missing the getData method from performance fix." -ForegroundColor Red +if ($appContent -notmatch "get_data") { + Write-Host "[FAIL] app.py is missing the get_data method from performance fix." -ForegroundColor Red Set-Location .. exit 1 } # Should NOT have experimental features -if ($appContent -match "experimentalMode") { - Write-Host "[FAIL] app.js contains experimental features (experimentalMode)." -ForegroundColor Red +if ($appContent -match "experimental_mode") { + Write-Host "[FAIL] app.py contains experimental features (experimental_mode)." -ForegroundColor Red Write-Host "Hint: You should cherry-pick ONLY the bug fixes, not experimental features" -ForegroundColor Yellow Write-Host " The experimental feature commits should stay on development branch only" -ForegroundColor Yellow Set-Location .. exit 1 } -if ($appContent -match "betaFeatures") { - Write-Host "[FAIL] app.js contains experimental features (betaFeatures)." -ForegroundColor Red +if ($appContent -match "beta_features") { + Write-Host "[FAIL] app.py contains experimental features (beta_features)." -ForegroundColor Red Write-Host "Hint: You should cherry-pick ONLY the bug fixes, not experimental features" -ForegroundColor Yellow Set-Location .. exit 1 } -if ($appContent -match "enableExperimentalFeatures") { - Write-Host "[FAIL] app.js contains experimental features (enableExperimentalFeatures)." -ForegroundColor Red +if ($appContent -match "enable_experimental_features") { + Write-Host "[FAIL] app.py contains experimental features (enable_experimental_features)." -ForegroundColor Red Write-Host "Hint: You should cherry-pick ONLY the bug fixes, not experimental features" -ForegroundColor Yellow Set-Location .. exit 1 diff --git a/module-09-reset-vs-revert/setup.ps1 b/module-09-reset-vs-revert/setup.ps1 index fc2693c..4d787d1 100644 --- a/module-09-reset-vs-revert/setup.ps1 +++ b/module-09-reset-vs-revert/setup.ps1 @@ -28,21 +28,16 @@ git config user.email "user@workshop.local" | Out-Null # Create initial commits on main $app = @" -class Calculator { - add(a, b) { - return a + b; - } +class Calculator: + def add(self, a, b): + return a + b - subtract(a, b) { - return a - b; - } -} - -module.exports = Calculator; + def subtract(self, a, b): + return a - b "@ -Set-Content -Path "calculator.js" -Value $app -git add calculator.js +Set-Content -Path "calculator.py" -Value $app +git add calculator.py git commit -m "Initial calculator implementation" | Out-Null $readme = @" @@ -59,54 +54,41 @@ git commit -m "Add README" | Out-Null git checkout -b local-feature | Out-Null $appWithMultiply = @" -class Calculator { - add(a, b) { - return a + b; - } +class Calculator: + def add(self, a, b): + return a + b - subtract(a, b) { - return a - b; - } + def subtract(self, a, b): + return a - b - multiply(a, b) { - return a * b; - } -} - -module.exports = Calculator; + def multiply(self, a, b): + return a * b "@ -Set-Content -Path "calculator.js" -Value $appWithMultiply -git add calculator.js +Set-Content -Path "calculator.py" -Value $appWithMultiply +git add calculator.py git commit -m "Add multiply function" | Out-Null # Add a bad commit that should be removed with reset $appWithBadCode = @" -class Calculator { - add(a, b) { - return a + b; - } +class Calculator: + def add(self, a, b): + return a + b - subtract(a, b) { - return a - b; - } + def subtract(self, a, b): + return a - b - multiply(a, b) { - return a * b; - } + def multiply(self, a, b): + return a * b - // BUG: This is broken and should never have been committed! - divide(a, b) { - // Forgot to check for division by zero - return a / b; // This will return Infinity or NaN for zero! - } -} - -module.exports = Calculator; + # BUG: This is broken and should never have been committed! + def divide(self, a, b): + # Forgot to check for division by zero + return a / b # This will raise ZeroDivisionError for zero! "@ -Set-Content -Path "calculator.js" -Value $appWithBadCode -git add calculator.js +Set-Content -Path "calculator.py" -Value $appWithBadCode +git add calculator.py git commit -m "Add broken divide function - DO NOT KEEP" | Out-Null # Switch back to main for shared-feature branch @@ -116,87 +98,70 @@ git checkout main | Out-Null git checkout -b shared-feature | Out-Null $appWithPower = @" -class Calculator { - add(a, b) { - return a + b; - } +class Calculator: + def add(self, a, b): + return a + b - subtract(a, b) { - return a - b; - } + def subtract(self, a, b): + return a - b - power(a, b) { - return Math.pow(a, b); - } -} - -module.exports = Calculator; + def power(self, a, b): + return a ** b "@ -Set-Content -Path "calculator.js" -Value $appWithPower -git add calculator.js +Set-Content -Path "calculator.py" -Value $appWithPower +git add calculator.py git commit -m "Add power function" | Out-Null # Add a bad commit that should be reverted (not reset) $appWithBrokenFeature = @" -class Calculator { - add(a, b) { - return a + b; - } +import math - subtract(a, b) { - return a - b; - } +class Calculator: + def add(self, a, b): + return a + b - power(a, b) { - return Math.pow(a, b); - } + def subtract(self, a, b): + return a - b - // BUG: This breaks the calculator! - squareRoot(a) { - // This implementation is wrong for negative numbers - return Math.sqrt(a); // Returns NaN for negative numbers without warning! - } -} + def power(self, a, b): + return a ** b -module.exports = Calculator; + # BUG: This breaks the calculator! + def square_root(self, a): + # This implementation is wrong for negative numbers + return math.sqrt(a) # Raises ValueError for negative numbers without warning! "@ -Set-Content -Path "calculator.js" -Value $appWithBrokenFeature -git add calculator.js +Set-Content -Path "calculator.py" -Value $appWithBrokenFeature +git add calculator.py git commit -m "Add broken feature" | Out-Null # Add another good commit after the bad one (to show that revert preserves subsequent commits) $appWithMoreFeatures = @" -class Calculator { - add(a, b) { - return a + b; - } +import math - subtract(a, b) { - return a - b; - } +class Calculator: + def add(self, a, b): + return a + b - power(a, b) { - return Math.pow(a, b); - } + def subtract(self, a, b): + return a - b - // BUG: This breaks the calculator! - squareRoot(a) { - // This implementation is wrong for negative numbers - return Math.sqrt(a); // Returns NaN for negative numbers without warning! - } + def power(self, a, b): + return a ** b - modulo(a, b) { - return a % b; - } -} + # BUG: This breaks the calculator! + def square_root(self, a): + # This implementation is wrong for negative numbers + return math.sqrt(a) # Raises ValueError for negative numbers without warning! -module.exports = Calculator; + def modulo(self, a, b): + return a % b "@ -Set-Content -Path "calculator.js" -Value $appWithMoreFeatures -git add calculator.js +Set-Content -Path "calculator.py" -Value $appWithMoreFeatures +git add calculator.py git commit -m "Add modulo function" | Out-Null # Switch to local-feature for the challenge start diff --git a/module-09-reset-vs-revert/verify.ps1 b/module-09-reset-vs-revert/verify.ps1 index ea2c142..7cf1bac 100644 --- a/module-09-reset-vs-revert/verify.ps1 +++ b/module-09-reset-vs-revert/verify.ps1 @@ -49,26 +49,26 @@ if ($localCommitCount -ne 3) { exit 1 } -# Check that calculator.js exists -if (-not (Test-Path "calculator.js")) { - Write-Host "[FAIL] calculator.js not found." -ForegroundColor Red +# Check that calculator.py exists +if (-not (Test-Path "calculator.py")) { + Write-Host "[FAIL] calculator.py not found." -ForegroundColor Red Set-Location .. exit 1 } -# Check calculator.js on local-feature -$localCalcContent = Get-Content "calculator.js" -Raw +# Check calculator.py on local-feature +$localCalcContent = Get-Content "calculator.py" -Raw # Should have multiply function if ($localCalcContent -notmatch "multiply") { - Write-Host "[FAIL] calculator.js should have the multiply function." -ForegroundColor Red + Write-Host "[FAIL] calculator.py should have the multiply function." -ForegroundColor Red Set-Location .. exit 1 } # Should NOT have divide function (it was in the bad commit that should be reset) if ($localCalcContent -match "divide") { - Write-Host "[FAIL] calculator.js should NOT have the divide function." -ForegroundColor Red + Write-Host "[FAIL] calculator.py should NOT have the divide function." -ForegroundColor Red Write-Host "Hint: Use 'git reset --hard HEAD~1' to remove the bad commit" -ForegroundColor Yellow Set-Location .. exit 1 @@ -115,27 +115,27 @@ if ($sharedCommits -notmatch "Revert") { exit 1 } -# Check calculator.js on shared-feature -$sharedCalcContent = Get-Content "calculator.js" -Raw +# Check calculator.py on shared-feature +$sharedCalcContent = Get-Content "calculator.py" -Raw # Should have power function if ($sharedCalcContent -notmatch "power") { - Write-Host "[FAIL] calculator.js should have the power function." -ForegroundColor Red + Write-Host "[FAIL] calculator.py should have the power function." -ForegroundColor Red Set-Location .. exit 1 } # Should have modulo function (commits after the reverted one should be preserved) if ($sharedCalcContent -notmatch "modulo") { - Write-Host "[FAIL] calculator.js should have the modulo function." -ForegroundColor Red + Write-Host "[FAIL] calculator.py should have the modulo function." -ForegroundColor Red Write-Host "Hint: Reverting should preserve commits made after the bad one" -ForegroundColor Yellow Set-Location .. exit 1 } -# Should NOT have squareRoot function (it was in the bad commit that should be reverted) -if ($sharedCalcContent -match "squareRoot") { - Write-Host "[FAIL] calculator.js should NOT have the squareRoot function." -ForegroundColor Red +# Should NOT have square_root function (it was in the bad commit that should be reverted) +if ($sharedCalcContent -match "square_root") { + Write-Host "[FAIL] calculator.py should NOT have the square_root function." -ForegroundColor Red Write-Host "Hint: The 'Add broken feature' commit should be reverted" -ForegroundColor Yellow Write-Host " Use: git revert " -ForegroundColor Yellow Set-Location .. @@ -146,7 +146,7 @@ if ($sharedCalcContent -match "squareRoot") { $revertCommitMessage = git log --grep="Revert" --pretty=format:"%s" -n 1 2>$null if ($revertCommitMessage -notmatch "broken feature") { Write-Host "[FAIL] The revert commit should mention 'broken feature'." -ForegroundColor Red - Write-Host "Hint: Make sure you reverted the correct commit (the one that added squareRoot)" -ForegroundColor Yellow + Write-Host "Hint: Make sure you reverted the correct commit (the one that added square_root)" -ForegroundColor Yellow Set-Location .. exit 1 } diff --git a/module-10-stash/setup.ps1 b/module-10-stash/setup.ps1 index 0b3369b..80481b3 100644 --- a/module-10-stash/setup.ps1 +++ b/module-10-stash/setup.ps1 @@ -27,28 +27,22 @@ git config user.email "user@workshop.local" | Out-Null # Create initial application on main $app = @" -class Application { - constructor() { - this.name = 'MyApp'; - this.version = '1.0.0'; - } +class Application: + def __init__(self): + self.name = 'MyApp' + self.version = '1.0.0' - start() { - console.log('Application started'); - this.authenticate(); - } + def start(self): + print('Application started') + self.authenticate() - authenticate() { - console.log('Authentication check'); - return true; - } -} - -module.exports = Application; + def authenticate(self): + print('Authentication check') + return True "@ -Set-Content -Path "app.js" -Value $app -git add app.js +Set-Content -Path "app.py" -Value $app +git add app.py git commit -m "Initial application" | Out-Null $readme = @" @@ -66,54 +60,44 @@ git checkout -b feature-login | Out-Null # Start working on login feature $loginInitial = @" -class LoginService { - constructor() { - this.users = new Map(); - } +from datetime import datetime - register(username, password) { - if (this.users.has(username)) { - throw new Error('User already exists'); - } - this.users.set(username, { password, createdAt: new Date() }); - return true; - } -} +class LoginService: + def __init__(self): + self.users = {} -module.exports = LoginService; + def register(self, username, password): + if username in self.users: + raise ValueError('User already exists') + self.users[username] = {'password': password, 'created_at': datetime.now()} + return True "@ -Set-Content -Path "login.js" -Value $loginInitial -git add login.js +Set-Content -Path "login.py" -Value $loginInitial +git add login.py git commit -m "Start login service implementation" | Out-Null # Add a critical bug to main branch (simulating a bug that was introduced) git checkout main | Out-Null $appWithBug = @" -class Application { - constructor() { - this.name = 'MyApp'; - this.version = '1.0.0'; - } +class Application: + def __init__(self): + self.name = 'MyApp' + self.version = '1.0.0' - start() { - console.log('Application started'); - this.authenticate(); - } + def start(self): + print('Application started') + self.authenticate() - authenticate() { - console.log('Authentication check'); - // BUG: This allows unauthenticated access! - return true; // Should check actual credentials - } -} - -module.exports = Application; + def authenticate(self): + print('Authentication check') + # BUG: This allows unauthenticated access! + return True # Should check actual credentials "@ -Set-Content -Path "app.js" -Value $appWithBug -git add app.js +Set-Content -Path "app.py" -Value $appWithBug +git add app.py git commit -m "Update authentication (contains bug)" | Out-Null # Go back to feature branch @@ -121,35 +105,29 @@ git checkout feature-login | Out-Null # Create work in progress (uncommitted changes) $loginWIP = @" -class LoginService { - constructor() { - this.users = new Map(); - } +from datetime import datetime - register(username, password) { - if (this.users.has(username)) { - throw new Error('User already exists'); - } - this.users.set(username, { password, createdAt: new Date() }); - return true; - } +class LoginService: + def __init__(self): + self.users = {} - // TODO: Complete this method - login(username, password) { - if (!this.users.has(username)) { - throw new Error('User not found'); - } - // TODO: Verify password - // TODO: Return user session - } + def register(self, username, password): + if username in self.users: + raise ValueError('User already exists') + self.users[username] = {'password': password, 'created_at': datetime.now()} + return True - // TODO: Add logout method -} + # TODO: Complete this method + def login(self, username, password): + if username not in self.users: + raise ValueError('User not found') + # TODO: Verify password + # TODO: Return user session -module.exports = LoginService; + # TODO: Add logout method "@ -Set-Content -Path "login.js" -Value $loginWIP +Set-Content -Path "login.py" -Value $loginWIP # Don't commit - leave as uncommitted changes @@ -169,10 +147,10 @@ Write-Host "1. Navigate to the challenge directory: cd challenge" -ForegroundCol Write-Host "2. Check your status: git status (see uncommitted changes)" -ForegroundColor White Write-Host "3. Stash your work: git stash save 'WIP: login feature'" -ForegroundColor White Write-Host "4. Switch to main: git checkout main" -ForegroundColor White -Write-Host "5. Fix the security bug in app.js (remove the comment and fix the auth)" -ForegroundColor White -Write-Host "6. Commit the fix: git add app.js && git commit -m 'Fix critical security bug'" -ForegroundColor White +Write-Host "5. Fix the security bug in app.py (remove the comment and fix the auth)" -ForegroundColor White +Write-Host "6. Commit the fix: git add app.py && git commit -m 'Fix critical security bug'" -ForegroundColor White Write-Host "7. Switch back: git checkout feature-login" -ForegroundColor White Write-Host "8. Restore your work: git stash pop" -ForegroundColor White -Write-Host "9. Complete the TODOs in login.js" -ForegroundColor White +Write-Host "9. Complete the TODOs in login.py" -ForegroundColor White Write-Host "10. Commit your completed feature" -ForegroundColor White Write-Host "`nRun '../verify.ps1' from the challenge directory to check your solution.`n" -ForegroundColor Cyan diff --git a/module-10-stash/verify.ps1 b/module-10-stash/verify.ps1 index 08939df..8c517d9 100644 --- a/module-10-stash/verify.ps1 +++ b/module-10-stash/verify.ps1 @@ -66,21 +66,21 @@ if ($mainCommits -notmatch "security bug|Fix.*bug|security fix") { exit 1 } -# Check that app.js has been fixed -if (-not (Test-Path "app.js")) { - Write-Host "[FAIL] app.js not found on main branch." -ForegroundColor Red +# Check that app.py has been fixed +if (-not (Test-Path "app.py")) { + Write-Host "[FAIL] app.py not found on main branch." -ForegroundColor Red git checkout feature-login 2>$null | Out-Null Set-Location .. exit 1 } -$appContent = Get-Content "app.js" -Raw +$appContent = Get-Content "app.py" -Raw # The bug was "return true" in authenticate - it should be fixed now # We'll check that the buggy comment is gone or the implementation is improved if ($appContent -match "allows unauthenticated access") { - Write-Host "[FAIL] The security bug comment still exists in app.js." -ForegroundColor Red - Write-Host "Hint: Remove the bug from app.js and commit the fix" -ForegroundColor Yellow + Write-Host "[FAIL] The security bug comment still exists in app.py." -ForegroundColor Red + Write-Host "Hint: Remove the bug from app.py and commit the fix" -ForegroundColor Yellow git checkout feature-login 2>$null | Out-Null Set-Location .. exit 1 @@ -103,26 +103,26 @@ if ($commitCount -lt 3) { exit 1 } -# Check that login.js exists -if (-not (Test-Path "login.js")) { - Write-Host "[FAIL] login.js not found on feature-login branch." -ForegroundColor Red +# Check that login.py exists +if (-not (Test-Path "login.py")) { + Write-Host "[FAIL] login.py not found on feature-login branch." -ForegroundColor Red Set-Location .. exit 1 } -$loginContent = Get-Content "login.js" -Raw +$loginContent = Get-Content "login.py" -Raw # Check that login method exists and is implemented if ($loginContent -notmatch "login\(username, password\)") { - Write-Host "[FAIL] login.js should have a login method." -ForegroundColor Red + Write-Host "[FAIL] login.py should have a login method." -ForegroundColor Red Set-Location .. exit 1 } # Check that TODOs are completed (no TODO comments should remain) if ($loginContent -match "TODO") { - Write-Host "[FAIL] login.js still contains TODO comments." -ForegroundColor Red - Write-Host "Hint: Complete all the TODOs in login.js before committing" -ForegroundColor Yellow + Write-Host "[FAIL] login.py still contains TODO comments." -ForegroundColor Red + Write-Host "Hint: Complete all the TODOs in login.py before committing" -ForegroundColor Yellow Set-Location .. exit 1 } @@ -155,7 +155,7 @@ if ($stashCount -gt 0) { # Verify the login implementation is complete if ($loginContent -notmatch "logout|session") { - Write-Host "[PARTIAL] login.js is missing logout or session functionality." -ForegroundColor Yellow + Write-Host "[PARTIAL] login.py is missing logout or session functionality." -ForegroundColor Yellow Write-Host "Consider adding logout method for a complete implementation" -ForegroundColor Yellow # Don't fail - this is just a suggestion } diff --git a/module-11-remotes/setup.ps1 b/module-11-remotes/setup.ps1 index 38dc80c..35f2a82 100644 --- a/module-11-remotes/setup.ps1 +++ b/module-11-remotes/setup.ps1 @@ -31,22 +31,17 @@ git config user.email "user@workshop.local" | Out-Null # Create initial project files $app = @" -class Application { - constructor() { - this.name = 'TeamProject'; - this.version = '1.0.0'; - } +class Application: + def __init__(self): + self.name = 'TeamProject' + self.version = '1.0.0' - start() { - console.log('Application started'); - } -} - -module.exports = Application; + def start(self): + print('Application started') "@ -Set-Content -Path "app.js" -Value $app -git add app.js +Set-Content -Path "app.py" -Value $app +git add app.py git commit -m "Initial application" | Out-Null $readme = @" @@ -63,17 +58,19 @@ git add README.md git commit -m "Add README" | Out-Null $package = @" -{ - "name": "team-project", - "version": "1.0.0", - "description": "Learning Git remotes", - "main": "app.js" -} +from setuptools import setup + +setup( + name='team-project', + version='1.0.0', + description='Learning Git remotes', + py_modules=['app'], +) "@ -Set-Content -Path "package.json" -Value $package -git add package.json -git commit -m "Add package.json" | Out-Null +Set-Content -Path "setup.py" -Value $package +git add setup.py +git commit -m "Add setup.py" | Out-Null # Create the "remote" repository (bare repository) Set-Location .. @@ -102,18 +99,17 @@ git config user.name "Teammate" 2>>`$null | Out-Null git config user.email "teammate@workshop.local" 2>>`$null | Out-Null # Make changes to main branch -`$appContent = Get-Content "app.js" -Raw -`$updatedApp = `$appContent -replace "start\(\) {", @" -start() { - console.log('Starting application...'); - this.initialize(); - } +`$appContent = Get-Content "app.py" -Raw +`$updatedApp = `$appContent -replace "def start\(self\):", @" +def start(self): + print('Starting application...') + self.initialize() - initialize() { + def initialize(self): "@ -Set-Content -Path "app.js" -Value `$updatedApp -git add app.js 2>>`$null +Set-Content -Path "app.py" -Value `$updatedApp +git add app.py 2>>`$null git commit -m "Add initialization method" 2>>`$null | Out-Null git push origin main 2>>`$null | Out-Null @@ -140,7 +136,7 @@ Write-Host "1. Navigate to the challenge directory: cd challenge" -ForegroundCol Write-Host "2. Clone the remote: git clone remote-repo local-repo" -ForegroundColor White Write-Host "3. Navigate to your clone: cd local-repo" -ForegroundColor White Write-Host "4. Create a feature branch: git checkout -b add-feature" -ForegroundColor White -Write-Host "5. Add a new method to app.js (e.g., stop method)" -ForegroundColor White +Write-Host "5. Add a new method to app.py (e.g., stop method)" -ForegroundColor White Write-Host "6. Commit your changes" -ForegroundColor White Write-Host "7. Push your branch: git push -u origin add-feature" -ForegroundColor White Write-Host "8. Go back to challenge directory: cd .." -ForegroundColor White diff --git a/module-11-remotes/verify.ps1 b/module-11-remotes/verify.ps1 index 1fd81c2..622d135 100644 --- a/module-11-remotes/verify.ps1 +++ b/module-11-remotes/verify.ps1 @@ -80,7 +80,7 @@ $mainCommitCount = (git rev-list --count main 2>$null) if ($featureCommitCount -le $mainCommitCount) { Write-Host "[FAIL] add-feature branch has no new commits." -ForegroundColor Red - Write-Host "Hint: Make changes to app.js and commit them on the add-feature branch" -ForegroundColor Yellow + Write-Host "Hint: Make changes to app.py and commit them on the add-feature branch" -ForegroundColor Yellow Set-Location ../.. exit 1 } @@ -103,20 +103,20 @@ Write-Host "[PASS] Feature branch pushed to remote!" -ForegroundColor Green Set-Location ../local-repo -# Check if app.js has been modified -if (-not (Test-Path "app.js")) { - Write-Host "[FAIL] app.js not found." -ForegroundColor Red +# Check if app.py has been modified +if (-not (Test-Path "app.py")) { + Write-Host "[FAIL] app.py not found." -ForegroundColor Red Set-Location ../.. exit 1 } -$appContent = Get-Content "app.js" -Raw +$appContent = Get-Content "app.py" -Raw # Check for user's changes (should have added something) $featureCommits = git log --pretty=format:"%s" add-feature 2>$null if (-not ($featureCommits -match "stop|feature|add" -or $appContent -match "stop")) { - Write-Host "[FAIL] No new feature detected in app.js." -ForegroundColor Red - Write-Host "Hint: Add a new method (like 'stop') to app.js and commit it" -ForegroundColor Yellow + Write-Host "[FAIL] No new feature detected in app.py." -ForegroundColor Red + Write-Host "Hint: Add a new method (like 'stop') to app.py and commit it" -ForegroundColor Yellow Set-Location ../.. exit 1 } diff --git a/module-12-worktrees/setup.ps1 b/module-12-worktrees/setup.ps1 index af3b759..4360a04 100644 --- a/module-12-worktrees/setup.ps1 +++ b/module-12-worktrees/setup.ps1 @@ -31,30 +31,23 @@ git config user.email "user@workshop.local" | Out-Null # Create initial calculator with a bug $calculator = @" -class Calculator { - add(a, b) { - return a + b; - } +class Calculator: + def add(self, a, b): + return a + b - subtract(a, b) { - return a - b; - } + def subtract(self, a, b): + return a - b - multiply(a, b) { - return a * b; - } + def multiply(self, a, b): + return a * b - // BUG: No division by zero check! - divide(a, b) { - return a / b; - } -} - -module.exports = Calculator; + # BUG: No division by zero check! + def divide(self, a, b): + return a / b "@ -Set-Content -Path "calculator.js" -Value $calculator -git add calculator.js +Set-Content -Path "calculator.py" -Value $calculator +git add calculator.py git commit -m "Initial calculator implementation" | Out-Null $readme = @" @@ -78,38 +71,30 @@ git checkout -b feature-advanced-math | Out-Null # Add work in progress on feature branch $calculatorWithFeature = @" -class Calculator { - add(a, b) { - return a + b; - } +class Calculator: + def add(self, a, b): + return a + b - subtract(a, b) { - return a - b; - } + def subtract(self, a, b): + return a - b - multiply(a, b) { - return a * b; - } + def multiply(self, a, b): + return a * b - // BUG: No division by zero check! - divide(a, b) { - return a / b; - } + # BUG: No division by zero check! + def divide(self, a, b): + return a / b - // New feature: power function (work in progress) - power(a, b) { - return Math.pow(a, b); - } + # New feature: power function (work in progress) + def power(self, a, b): + return a ** b - // TODO: Add square root function - // TODO: Add logarithm function -} - -module.exports = Calculator; + # TODO: Add square root function + # TODO: Add logarithm function "@ -Set-Content -Path "calculator.js" -Value $calculatorWithFeature -git add calculator.js +Set-Content -Path "calculator.py" -Value $calculatorWithFeature +git add calculator.py git commit -m "Add power function (WIP: more math functions coming)" | Out-Null # Return to challenge directory @@ -128,11 +113,11 @@ Write-Host "`nYour task:" -ForegroundColor Yellow Write-Host "1. Navigate to main-repo: cd challenge/main-repo" -ForegroundColor White Write-Host "2. Create a worktree: git worktree add ../bugfix-worktree -b bugfix" -ForegroundColor White Write-Host "3. Go to worktree: cd ../bugfix-worktree" -ForegroundColor White -Write-Host "4. Fix the bug in calculator.js:" -ForegroundColor White +Write-Host "4. Fix the bug in calculator.py:" -ForegroundColor White Write-Host " Add a check: if (b === 0) throw new Error('Division by zero');" -ForegroundColor White Write-Host "5. Commit the fix: git add . && git commit -m 'Fix divide by zero bug'" -ForegroundColor White Write-Host "6. Return to main-repo: cd ../main-repo" -ForegroundColor White -Write-Host "7. Complete your feature: Add square root method to calculator.js" -ForegroundColor White +Write-Host "7. Complete your feature: Add square root method to calculator.py" -ForegroundColor White Write-Host "8. Commit: git add . && git commit -m 'Add square root function'" -ForegroundColor White Write-Host "9. Clean up worktree: git worktree remove ../bugfix-worktree" -ForegroundColor White Write-Host "`nRun '../verify.ps1' from the challenge directory to check your solution.`n" -ForegroundColor Cyan diff --git a/module-12-worktrees/verify.ps1 b/module-12-worktrees/verify.ps1 index a04f4e9..d5e779f 100644 --- a/module-12-worktrees/verify.ps1 +++ b/module-12-worktrees/verify.ps1 @@ -55,13 +55,13 @@ Write-Host "[PASS] Bugfix branch exists!" -ForegroundColor Green # Check bugfix branch for the fix git checkout bugfix 2>$null | Out-Null -if (-not (Test-Path "calculator.js")) { - Write-Host "[FAIL] calculator.js not found on bugfix branch." -ForegroundColor Red +if (-not (Test-Path "calculator.py")) { + Write-Host "[FAIL] calculator.py not found on bugfix branch." -ForegroundColor Red Set-Location ../.. exit 1 } -$bugfixCalc = Get-Content "calculator.js" -Raw +$bugfixCalc = Get-Content "calculator.py" -Raw # Check if division by zero check was added if ($bugfixCalc -notmatch "b === 0|b == 0|division by zero|divide by zero") { @@ -85,12 +85,12 @@ Write-Host "[PASS] Bug fixed on bugfix branch!" -ForegroundColor Green # Check feature branch for continued work git checkout feature-advanced-math 2>$null | Out-Null -$featureCalc = Get-Content "calculator.js" -Raw +$featureCalc = Get-Content "calculator.py" -Raw # Check if square root function was added if ($featureCalc -notmatch "sqrt|squareRoot") { Write-Host "[FAIL] Square root function not found on feature branch." -ForegroundColor Red - Write-Host "Hint: Add the square root method to calculator.js on feature-advanced-math branch" -ForegroundColor Yellow + Write-Host "Hint: Add the square root method to calculator.py on feature-advanced-math branch" -ForegroundColor Yellow Set-Location ../.. exit 1 } diff --git a/module-13-bisect/setup.ps1 b/module-13-bisect/setup.ps1 index d6849c0..037c158 100644 --- a/module-13-bisect/setup.ps1 +++ b/module-13-bisect/setup.ps1 @@ -27,327 +27,261 @@ git config user.email "user@workshop.local" | Out-Null # Commit 1: Initial calculator $calc1 = @" -class Calculator { - add(a, b) { - return a + b; - } -} - -module.exports = Calculator; +class Calculator: + def add(self, a, b): + return a + b "@ -Set-Content -Path "calculator.js" -Value $calc1 -git add calculator.js +Set-Content -Path "calculator.py" -Value $calc1 +git add calculator.py git commit -m "Initial calculator with add function" | Out-Null # Commit 2: Add subtract $calc2 = @" -class Calculator { - add(a, b) { - return a + b; - } +class Calculator: + def add(self, a, b): + return a + b - subtract(a, b) { - return a - b; - } -} - -module.exports = Calculator; + def subtract(self, a, b): + return a - b "@ -Set-Content -Path "calculator.js" -Value $calc2 -git add calculator.js +Set-Content -Path "calculator.py" -Value $calc2 +git add calculator.py git commit -m "Add subtract function" | Out-Null # Commit 3: Add multiply $calc3 = @" -class Calculator { - add(a, b) { - return a + b; - } +class Calculator: + def add(self, a, b): + return a + b - subtract(a, b) { - return a - b; - } + def subtract(self, a, b): + return a - b - multiply(a, b) { - return a * b; - } -} - -module.exports = Calculator; + def multiply(self, a, b): + return a * b "@ -Set-Content -Path "calculator.js" -Value $calc3 -git add calculator.js +Set-Content -Path "calculator.py" -Value $calc3 +git add calculator.py git commit -m "Add multiply function" | Out-Null # Commit 4: Add divide $calc4 = @" -class Calculator { - add(a, b) { - return a + b; - } +class Calculator: + def add(self, a, b): + return a + b - subtract(a, b) { - return a - b; - } + def subtract(self, a, b): + return a - b - multiply(a, b) { - return a * b; - } + def multiply(self, a, b): + return a * b - divide(a, b) { - if (b === 0) throw new Error('Division by zero'); - return a / b; - } -} - -module.exports = Calculator; + def divide(self, a, b): + if b == 0: + raise ValueError('Division by zero') + return a / b "@ -Set-Content -Path "calculator.js" -Value $calc4 -git add calculator.js +Set-Content -Path "calculator.py" -Value $calc4 +git add calculator.py git commit -m "Add divide function" | Out-Null # Commit 5: Add modulo $calc5 = @" -class Calculator { - add(a, b) { - return a + b; - } +class Calculator: + def add(self, a, b): + return a + b - subtract(a, b) { - return a - b; - } + def subtract(self, a, b): + return a - b - multiply(a, b) { - return a * b; - } + def multiply(self, a, b): + return a * b - divide(a, b) { - if (b === 0) throw new Error('Division by zero'); - return a / b; - } + def divide(self, a, b): + if b == 0: + raise ValueError('Division by zero') + return a / b - modulo(a, b) { - return a % b; - } -} - -module.exports = Calculator; + def modulo(self, a, b): + return a % b "@ -Set-Content -Path "calculator.js" -Value $calc5 -git add calculator.js +Set-Content -Path "calculator.py" -Value $calc5 +git add calculator.py git commit -m "Add modulo function" | Out-Null # Commit 6: BUG - Introduce error in add function $calc6 = @" -class Calculator { - add(a, b) { - return a - b; // BUG: Should be a + b - } +class Calculator: + def add(self, a, b): + return a - b # BUG: Should be a + b - subtract(a, b) { - return a - b; - } + def subtract(self, a, b): + return a - b - multiply(a, b) { - return a * b; - } + def multiply(self, a, b): + return a * b - divide(a, b) { - if (b === 0) throw new Error('Division by zero'); - return a / b; - } + def divide(self, a, b): + if b == 0: + raise ValueError('Division by zero') + return a / b - modulo(a, b) { - return a % b; - } -} - -module.exports = Calculator; + def modulo(self, a, b): + return a % b "@ -Set-Content -Path "calculator.js" -Value $calc6 -git add calculator.js +Set-Content -Path "calculator.py" -Value $calc6 +git add calculator.py git commit -m "Refactor add function for clarity" | Out-Null # Commit 7: Add power function (bug still exists) $calc7 = @" -class Calculator { - add(a, b) { - return a - b; // BUG: Should be a + b - } +class Calculator: + def add(self, a, b): + return a - b # BUG: Should be a + b - subtract(a, b) { - return a - b; - } + def subtract(self, a, b): + return a - b - multiply(a, b) { - return a * b; - } + def multiply(self, a, b): + return a * b - divide(a, b) { - if (b === 0) throw new Error('Division by zero'); - return a / b; - } + def divide(self, a, b): + if b == 0: + raise ValueError('Division by zero') + return a / b - modulo(a, b) { - return a % b; - } + def modulo(self, a, b): + return a % b - power(a, b) { - return Math.pow(a, b); - } -} - -module.exports = Calculator; + def power(self, a, b): + return a ** b "@ -Set-Content -Path "calculator.js" -Value $calc7 -git add calculator.js +Set-Content -Path "calculator.py" -Value $calc7 +git add calculator.py git commit -m "Add power function" | Out-Null # Commit 8: Add square root $calc8 = @" -class Calculator { - add(a, b) { - return a - b; // BUG: Should be a + b - } +import math - subtract(a, b) { - return a - b; - } +class Calculator: + def add(self, a, b): + return a - b # BUG: Should be a + b - multiply(a, b) { - return a * b; - } + def subtract(self, a, b): + return a - b - divide(a, b) { - if (b === 0) throw new Error('Division by zero'); - return a / b; - } + def multiply(self, a, b): + return a * b - modulo(a, b) { - return a % b; - } + def divide(self, a, b): + if b == 0: + raise ValueError('Division by zero') + return a / b - power(a, b) { - return Math.pow(a, b); - } + def modulo(self, a, b): + return a % b - sqrt(a) { - return Math.sqrt(a); - } -} + def power(self, a, b): + return a ** b -module.exports = Calculator; + def sqrt(self, a): + return math.sqrt(a) "@ -Set-Content -Path "calculator.js" -Value $calc8 -git add calculator.js +Set-Content -Path "calculator.py" -Value $calc8 +git add calculator.py git commit -m "Add square root function" | Out-Null # Commit 9: Add absolute value $calc9 = @" -class Calculator { - add(a, b) { - return a - b; // BUG: Should be a + b - } +import math - subtract(a, b) { - return a - b; - } +class Calculator: + def add(self, a, b): + return a - b # BUG: Should be a + b - multiply(a, b) { - return a * b; - } + def subtract(self, a, b): + return a - b - divide(a, b) { - if (b === 0) throw new Error('Division by zero'); - return a / b; - } + def multiply(self, a, b): + return a * b - modulo(a, b) { - return a % b; - } + def divide(self, a, b): + if b == 0: + raise ValueError('Division by zero') + return a / b - power(a, b) { - return Math.pow(a, b); - } + def modulo(self, a, b): + return a % b - sqrt(a) { - return Math.sqrt(a); - } + def power(self, a, b): + return a ** b - abs(a) { - return Math.abs(a); - } -} + def sqrt(self, a): + return math.sqrt(a) -module.exports = Calculator; + def abs(self, a): + return abs(a) "@ -Set-Content -Path "calculator.js" -Value $calc9 -git add calculator.js +Set-Content -Path "calculator.py" -Value $calc9 +git add calculator.py git commit -m "Add absolute value function" | Out-Null # Commit 10: Add max function $calc10 = @" -class Calculator { - add(a, b) { - return a - b; // BUG: Should be a + b - } +import math - subtract(a, b) { - return a - b; - } +class Calculator: + def add(self, a, b): + return a - b # BUG: Should be a + b - multiply(a, b) { - return a * b; - } + def subtract(self, a, b): + return a - b - divide(a, b) { - if (b === 0) throw new Error('Division by zero'); - return a / b; - } + def multiply(self, a, b): + return a * b - modulo(a, b) { - return a % b; - } + def divide(self, a, b): + if b == 0: + raise ValueError('Division by zero') + return a / b - power(a, b) { - return Math.pow(a, b); - } + def modulo(self, a, b): + return a % b - sqrt(a) { - return Math.sqrt(a); - } + def power(self, a, b): + return a ** b - abs(a) { - return Math.abs(a); - } + def sqrt(self, a): + return math.sqrt(a) - max(a, b) { - return a > b ? a : b; - } -} + def abs(self, a): + return abs(a) -module.exports = Calculator; + def max(self, a, b): + return a if a > b else b "@ -Set-Content -Path "calculator.js" -Value $calc10 -git add calculator.js +Set-Content -Path "calculator.py" -Value $calc10 +git add calculator.py git commit -m "Add max function" | Out-Null # Create a test file $test = @" -const Calculator = require('./calculator.js'); -const calc = new Calculator(); +import sys +from calculator import Calculator -// Test addition (this will fail due to bug) -const result = calc.add(5, 3); -if (result !== 8) { - console.log('FAIL: add(5, 3) returned ' + result + ', expected 8'); - process.exit(1); -} +calc = Calculator() -console.log('PASS: All tests passed'); -process.exit(0); +# Test addition (this will fail due to bug) +result = calc.add(5, 3) +if result != 8: + print(f'FAIL: add(5, 3) returned {result}, expected 8') + sys.exit(1) + +print('PASS: All tests passed') +sys.exit(0) "@ -Set-Content -Path "test.js" -Value $test +Set-Content -Path "test.py" -Value $test # Return to module directory Set-Location .. @@ -363,11 +297,11 @@ Write-Host "Manually checking each commit would be tedious." -ForegroundColor Ye Write-Host "Use git bisect to find it efficiently!" -ForegroundColor Green Write-Host "`nYour task:" -ForegroundColor Yellow Write-Host "1. Navigate to the challenge directory: cd challenge" -ForegroundColor White -Write-Host "2. Test the bug: node test.js (it will fail)" -ForegroundColor White +Write-Host "2. Test the bug: python test.py (it will fail)" -ForegroundColor White Write-Host "3. Start bisect: git bisect start" -ForegroundColor White Write-Host "4. Mark current as bad: git bisect bad" -ForegroundColor White Write-Host "5. Mark old commit as good: git bisect good HEAD~10" -ForegroundColor White -Write-Host "6. Git will checkout a commit - test it: node test.js" -ForegroundColor White +Write-Host "6. Git will checkout a commit - test it: python test.py" -ForegroundColor White Write-Host "7. Mark result: git bisect good (if test passes) or git bisect bad (if it fails)" -ForegroundColor White Write-Host "8. Repeat until Git finds the first bad commit" -ForegroundColor White Write-Host "9. Note the commit hash" -ForegroundColor White diff --git a/module-13-bisect/verify.ps1 b/module-13-bisect/verify.ps1 index 784d9e3..2647577 100644 --- a/module-13-bisect/verify.ps1 +++ b/module-13-bisect/verify.ps1 @@ -89,7 +89,7 @@ if ($userCommit -ne $actualBadCommit) { Write-Host " git bisect start" -ForegroundColor White Write-Host " git bisect bad" -ForegroundColor White Write-Host " git bisect good HEAD~10" -ForegroundColor White - Write-Host " # Then test with: node test.js" -ForegroundColor White + Write-Host " # Then test with: node test.py" -ForegroundColor White Write-Host " git bisect good # or bad" -ForegroundColor White Set-Location .. exit 1 @@ -100,7 +100,7 @@ if ($userCommit -ne $actualBadCommit) { # Verify the commit actually has the bug git checkout $actualBadCommit 2>$null | Out-Null -$calcContent = Get-Content "calculator.js" -Raw +$calcContent = Get-Content "calculator.py" -Raw if ($calcContent -notmatch "add\(a, b\)[\s\S]*?return a - b") { Write-Host "[WARNING] The identified commit doesn't seem to have the expected bug." -ForegroundColor Yellow