Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions .github/workflows/python-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Run Python Tests

on:
pull_request:
branches:
- main
workflow_dispatch:


jobs:
test:
name: Test
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
cache: 'pip'
- name: Install pytest
run: |
python -m pip install --upgrade pip
python -m pip install pytest
- name: Run tests
run: |
pytest -q code-challenges
env:
CI: true


8 changes: 7 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -227,5 +227,11 @@ $RECYCLE.BIN/
# Visual Studio 2015/2017 cache/options directory
.vs/

# Python
__pycache__/
.pytest_cache/
*.py[cod]
.venv/
.coverage
.mypy_cache/

# End of https://www.gitignore.io/api/node,macos,linux,windows,webstorm,visualstudiocode
75 changes: 64 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,68 @@
# Data Structures and Algorithms

## 301 Code Challenges
### JavaScript Setup

Use Node.js LTS and Yarn (recommended) to install and run tests.

Node setup (optional, via nvm):
```bash
nvm install --lts
nvm use --lts
node -v
```

Install dependencies and run tests (Yarn):
```bash
cd <root>
yarn
yarn test
```

If Yarn is not available:
```bash
# Option A: use Corepack to activate the repo-pinned Yarn 1.x
corepack enable
corepack prepare yarn@1.22.22 --activate

# Option B: install globally (classic Yarn)
npm i -g yarn
```

Using npm instead of Yarn:
```bash
npm ci
npm test
```

Handy commands:
- Run a specific Jest test file: `yarn test code-challenges/challenges-01.test.js`
- Lint JavaScript: `yarn lint`

### Python Setup

Set up a local Python environment and run tests:

```bash
cd /Users/tomm/repos/data-structures-and-algorithms
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -U pip pytest
pytest --version
```

Run tests:
- All Python challenges: `pytest -q code-challenges`
- Single file: `pytest -q code-challenges/challenges_01_test.py`

Pytest test discovery:
- Default patterns: `test_*.py` or `*_test.py`
- If you prefer “.test.py” names, add a `pytest.ini` at the repo root:
```
[pytest]
python_files = *.test.py test_*.py *_test.py
```

## 301 Code Challenges (JavaScript)

[forEach](code-challenges/challenges-01.test.js)

Expand Down Expand Up @@ -55,15 +117,6 @@

[Tree Intersection](javascript/trees/binary-tree/tree-intersection/README.md)


### Misc

[JavaScript Folder Setup](javascript/README.md)

### Sources

[301 Setup Instructions](https://codefellows.github.io/setup-guide/code-301/3-code-challenges)




[JavaScript Folder Setup](javascript/README.md)
199 changes: 199 additions & 0 deletions code-challenges/challenges_01_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
'''
------------------------------------------------------------------------------------------------
CHALLENGE 1

Write a function named `addOne` that takes an array of numbers, and returns a new array of the numbers, incremented by 1.

Use `forLoop` to loop over the input array and work with each value. Push the new value into a local array. Return the local array;
------------------------------------------------------------------------------------------------
'''

def addOne(arr):
result = []
for num in arr:
result.append(num + 1)
return result

'''
CHALLENGE 2

Write a function named `addExclamation` that takes an array of strings, and returns a new array of the same strings with an "!" added to the end.

Use `forLoop` to loop over the input array. Modify each string, and add the updated value into a local array. Return the local array;
'''

def addExclamation(arr):
result = []
for string in arr:
result.append(string + '!')
return result

'''
------------------------------------------------------------------------------------------------
CHALLENGE 3

Write a function named `allUpperCase` that takes an array of strings, and returns a new array of the strings converted to upper case.

Use `forLoop` to loop over the input array. The modified strings should each be added into a local array. Return that local array.
------------------------------------------------------------------------------------------------
'''

def allUpperCase(arr):
result = []
for string in arr:
result.append(string.upper())
return result

'''
------------------------------------------------------------------------------------------------
CHALLENGE 4

Write a function named `greeting` that takes in a single string and returns the string in all uppercase letters, and followed by an "!".

Then, write a function named `speaker` that takes in an array of strings and a callback function.

Use `forLoop` to build a new array of strings, each string modified by the callback. Return the new array.
------------------------------------------------------------------------------------------------
'''

def greeting(word):
return word.upper() + '!'

def speaker(words, callback):
result = []
for word in words:
result.append(callback(word))
return result

'''
------------------------------------------------------------------------------------------------
CHALLENGE 5

Write a function named addValues that takes in an array and a value and pushes the value into the array. This function does not need a return statement.

Then, write a function named addNumbers that takes in four arguments:
- A number to be added to an array
- An array into which the number should be added
- The number of times the number should be added
- A callback function to use to add the numbers to the array (Hint: you already defined it)

Within the addNumbers function, invoke the callback function as many times as necessary, based on the third argument of the addNumbers function.

Return the modified array.
------------------------------------------------------------------------------------------------
'''

def addValues(arr, value):
arr.append(value)

def addNumbers(num, arr, times, callback):
for i in range(times):
callback(arr, num)
return arr

'''
------------------------------------------------------------------------------------------------

CHALLENGE 6

Write a function named createList that takes in an array of the current store inventory.

The inventory is formatted like this:
[
{ name: 'apples', available: true },
{ name: 'pears', available: true },
{ name: 'oranges', available: false },
{ name: 'bananas', available: true },
{ name: 'blueberries', available: false }
]

This function should use forEach to populate your grocery list based on the store's inventory. If the item is available, add it to your list. Return the final list.
------------------------------------------------------------------------------------------------
'''

def createList(availableItems):
result = []
for item in availableItems:
if item['available']:
result.append(item['name'])
return result

'''
------------------------------------------------------------------------------------------------
STRETCH - CHALLENGE 7

Write a function named fizzbuzz that takes in an array of numbers.

Iterate over the array using forEach to determine the output based on several rules:
- If a number is divisible by 3, add the word "Fizz" to the output array.
- If the number is divisible by 5, add the word "Buzz" to the output array.
- If the number is divisible by both 3 and 5, add the phrase "Fizz Buzz" to the output array.
- Otherwise, add the number to the output array.

Return the resulting output array.
------------------------------------------------------------------------------------------------
'''

def fizzbuzz(arr):
result = []
for num in arr:
if num % 3 == 0 and num % 5 == 0:
result.append('Fizz Buzz')
elif num % 3 == 0:
result.append('Fizz')
elif num % 5 == 0:
result.append('Buzz')
else:
result.append(num)
return result

'''
TESTS

All the code below will verify that your functions are working to solve the challenges.

DO NOT CHANGE any of the below code.

Run your tests with pytest:
- Directly (works even if filename doesn't match default discovery):
pytest -q code-challenges/challenges-01.test.py
- Or configure discovery (optional). Create a pytest.ini with:
[pytest]
python_files = *.test.py
'''

def test_add_one():
assert addOne([1, 2, 3, 4, 5]) == [2, 3, 4, 5, 6]

def test_add_exclamation():
assert addExclamation(['hi', 'how', 'are', 'you']) == ['hi!', 'how!', 'are!', 'you!']

def test_all_upper_case():
assert allUpperCase(['hi', 'how', 'are', 'you']) == ['HI', 'HOW', 'ARE', 'YOU']

def test_speaker_with_greeting():
assert speaker(['hello', '301', 'students'], greeting) == ['HELLO!', '301!', 'STUDENTS!']

def test_add_numbers():
result = addNumbers(8, [], 5, addValues)
assert result == [8, 8, 8, 8, 8]
assert len(result) == 5

def test_create_list():
inventory = [
{ 'name': 'apples', 'available': True },
{ 'name': 'pears', 'available': True },
{ 'name': 'oranges', 'available': False },
{ 'name': 'bananas', 'available': True },
{ 'name': 'blueberries', 'available': False },
]
result = createList(inventory)
assert result == ['apples', 'pears', 'bananas']
assert len(result) == 3

def test_fizzbuzz():
inputs = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
expected = [1, 2, 'Fizz', 4, 'Buzz', 'Fizz', 7, 8, 'Fizz', 'Buzz', 11, 'Fizz', 13, 14, 'Fizz Buzz', 16]
result = fizzbuzz(inputs)
assert result == expected
assert len(result) == 16
3 changes: 3 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pytest>=9,<10