Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
fa5d405
First successful test built
samannetts8 Jan 16, 2025
fe26ce2
Wrote Challenge Description in main.js
samannetts8 Jan 16, 2025
a68f22f
Rebuilt test to function as a test.each
samannetts8 Jan 16, 2025
98b37bb
Corrected test description
samannetts8 Jan 16, 2025
aec703c
Include tests for comparing filtering on individual keys
samannetts8 Jan 16, 2025
2812e63
Successful tests for all types of individual key responses
samannetts8 Jan 16, 2025
c731c85
Created test for multiple search terms
samannetts8 Jan 16, 2025
1299921
Completed function that takes in multiple inputs
samannetts8 Jan 16, 2025
8b8c122
Additional tests added for multiple attributes
samannetts8 Jan 16, 2025
819a8a7
Refactored function to pass "Comparing filtering on multiple keys (in…
samannetts8 Jan 16, 2025
8c14d90
Additional "Comparing filtering on multiple keys (incl colours)" tests
samannetts8 Jan 16, 2025
26c7384
Output Validation Test included
samannetts8 Jan 16, 2025
4c7d40e
Progressed markdown file
samannetts8 Jan 17, 2025
4327596
Updated markdown file
samannetts8 Jan 17, 2025
d02790b
Updated edge case test function
samannetts8 Jan 17, 2025
a38b693
Final Kata (With Solution)
samannetts8 Jan 17, 2025
563e5c7
Final Kata (Without Solution)
samannetts8 Jan 17, 2025
f821497
Added Object.freeze() method to FULL_FLAG_LIST
samannetts8 Feb 15, 2025
2f29163
Updated Project README
samannetts8 Feb 15, 2025
26accbe
Merge branch 'main' into SolutionBranch
samannetts8 Feb 15, 2025
e5bd537
Updated main.js
samannetts8 Feb 15, 2025
241cd22
Updated README and Solution Removed
samannetts8 Feb 15, 2025
fa2165c
Rename README
samannetts8 Feb 15, 2025
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
8 changes: 7 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
node_modules/
node_modules/
coverage
junk*
/test-results/
/playwright-report/
/blob-report/
/playwright/.cache/
1 change: 0 additions & 1 deletion PROJECT_PRESENTATION.md

This file was deleted.

145 changes: 63 additions & 82 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,114 +1,95 @@
# Make your own Codewars Style Challenge
# Flagging Down the Answer

In this workshop, you'll create your own programming challenge for others to solve, similar to the ones you might have tackled on Codewars. You'll write unit tests to validate solutions. Then you can share your challenge with other bootcampers for them to solve. If a submitted solution passes all your tests, it will be considered a correct solution - just like on Codewars. This is a great chance to get creative and come up with a programming challenge to stump your peers!
## Project Summary

## 💡 OBJECTIVES FOR THE WORKSHOP
The aim of this project was to create a fun and engaging Javascript challenge that would test its user's ability to interact with object arguments and use the provided information to return an array of valid matches.

Here's a glimpse of what you'll be achieving by the end of this workshop:
## Project Description

- Clearly describing a problem/task that you want others to solve
- Writing unit tests to check whether their solution to your task is correct
- Present your project plan, story, and anything else you feel supports your creation process and final outcome in a document
For this project, you are aiming to create a function that filters a list of countries based on the characteristics of their flags. The function, filterFlag, takes two arguments: an object containing the search terms (characteristics of the flag) and an array of flag data (FULL_FLAG_LIST). The function returns an array of country names that match the given characteristics.

## 🎟️ TICKETS
- [Installation](#installation)
- [Data Structure](#data-structure)
- [Testing](#testing)
- [Function Requirements](#Function-Requirements)
- [Constraints](#Constraints)
- [Example Usage](#Example-Usage)
- [Evaluation Criteria](#Evaluation-Criteria)
- [Project Requirements](#Project-Requirements)

Time to dive into action! 🏊‍♂️ Here's what you'll be working on:
## Installation

### 🎫 Ticket 1 - Setup
1. Clone the repository:
```sh
git clone https://github.com/samannetts/flag-identification.git
```
2. Install the dependencies:
```sh
npm install
```

Install Vitest and optionally set up an NPM `test` script that conveniently runs your tests.
### Data Structures

You will be making one kata each, but you will be in development teams. The aim is to co-elevate each other. There are several ways you can and should look to help each other:
Each country's flag is represented by an object with the following keys:

- Brainstorming: Helping each make your ideas better, and giving feedback to each other to add different perspectives and improve the end product
- Planning: You can help validate each others plans, and sense check in a team review the direction of your products
- Check-ins: Regular team stand-ups / check-ins will help make sure you are building and making progress together
- Support: You should aim to help each other overcome issues if one of your team is stuck and cannot Google their way out of it
- Testing: You can act as a first line user test for each others katas. You might find it a good idea to book in regular checkpoints to demo to each other and get initial feedback in quick bursts, making sure you can build in and adapt to any useful feedback before official release of your katas
- `country`: string
- `hasStripes`: boolean
- `numberOfColors`: int
- `hasStars`: boolean
- `stripeDirection`: string (can be "horizontal", "vertical" or null)
- `hasCircles`: boolean
- `colours`: [string, string, string] (an array containing varying number of strings)

### 🎫 Ticket 2 - Plan your kata
### Testing

Attack this as you would any other problem - plan, plan, plan and use our agile approach to create steps that allow you to build MVPs and incrementally reach your stretch goals. Brainstorm options with a technique like Disney Ideation. Once you have a compelling challenge and story idea, start breaking it down. Think about the goals of your challenge, and the scenarios you could provide to test if people have reached those goals. Provide any examples or additional details that are necessary for someone taking on your kata to understand the problem, but don't give away so much that it removes the challenge. You want to strike a balance - not too vague but not spoon-feeding the solution either.
To run the tests, use the following command:

Write your kata's scenario in a comment in `main.js` and include the start of an exported function that your audience will use to solve it (like you've seen on the katas you've done before). If it's useful to see an example:

```js
/**
* Hello challenger! Your task is to write a function named `transformLength` which takes in a string and returns 1 if the length of the string is even and otherwise -1.
*
* Your implementation should handle strings whose length is between 0 (inclusive) and 2500 (inclusive).
*
* A few examples:
* `transformLength("table")` should return -1 as the length of "table" is not even
* `transformLength("wizard")` should return 1 as the length of "wizard" is even
*/
export function transformLength(string) {
// Good luck!
}
```sh
npm test
```

ℹ️ The reason for leaving the function body empty is that you want the people solving your kata to write their own implementation from scratch. Your role is to provide the overall problem statement and function skeleton. The solving and coding is up to them! Leaving an incomplete skeleton function helps point them in the right direction without giving away a full working solution.

### 🎫 Ticket 3 - Write your kata

When drafting your test cases, consider the different inputs that could be passed to the solution function and any edge cases you want to account for. You could put into practice tools such as Equivalency Partitioning, Boundary Value Analysis, and Decision Tables if its useful. Think of test values that will thoroughly cover the expected functionality. The number of tests is up to you, but aim for sufficient coverage to validate correctness.

Since you'll write tests before seeing people's solutions, focus on defining expected outputs for given inputs, without assumptions about how people actually wrote the code. You're testing for outcomes. You could follow a TDD workflow - write a failing test, then temporarily add code to pass it. Just be sure to remove the solution code before sharing the kata. This helps ensure your tests fail when logic is missing or incorrect and pass when implemented properly.

If it's useful to see an example (continuing the `checkLength` example from earlier):
Ensure that Vitest is installed as a development dependency:

```js
import { test, expect } from "vitest";
import { checkLength } from "./main.js";

test("should return -1 for strings with an odd length", () => {
const expected = -1;
const actual = checkLength("table");
expect(actual).toBe(expected);
});

test("should return 1 for strings with an even length", () => {
const expected = 1;
const actual = checkLength("wizard");
expect(actual).toBe(expected);
});
```sh
npm install --save-dev vitest
```

🎯 At this stage you should have a description of the problem in `main.js` and some tests in `main.test.js`.
Ensure that Vitest is installed as a development dependency:

### 🎫 Ticket 4 - Check your tests
### Function Requirements

To verify your tests, temporarily add a working implementation to the solution function in `main.js`. Check that the tests fail before implementation and pass when the function is coded correctly. This validates that your tests accurately check for both incorrect and correct solutions. Remember to remove the solution code afterwards before sharing the kata.
The `filterFlag` function should:

If it's useful to see an example (continuing the `checkLength` example from earlier):
1. Handle input objects with varying sets of characteristics.
2. Return the names of the countries that match the given characteristics.

```js
export function checkLength(string) {
// Temporarily added the line below to check if tests pass, but will remove it before committing and pushing.
return string.length % 2 === 0 ? 1 : -1;
}
```
### Constraints

### 🎫 Ticket 5 - Share your kata
Input Constraints:

Before pushing your final kata repository, be sure to remove any solution code you added for test validation. You want to provide only the kata description, skeleton function, and test cases - no actual solutions. Once ready, share your repo link in the [learn.schoolofcode.co.uk Hackathon Channel](https://learn.schoolofcode.co.uk/path-player?courseid=bc17-qe&unit=66acf966524bf23f05018063Unit) so other bootcampers can find it, clone it, implement solutions, and run your tests to check their progress. This allows them to solve the programming challenge you've created!
- The function must handle input objects with up to 6 keys.
- Input will never be null.
- All input keys will have corresponding values in the `FULL_FLAG_LIST` object.
- The function should return an array of strings representing country names.

Share it with following format:
Output Format:

```
Room: REPLACE_ME_WITH_YOUR_ROOM_NUMBER
Name: REPLACE_ME_WITH_YOUR_NAME
Link: REPLACE_ME_WITH_A_LINK_TO_YOUR_PUBLIC_GITHUB_REPO_CONTAINING_THE_KATA
Overview: REPLACE_ME_WITH_A_BRIEF_DESCRIPTION_OF_WHAT_YOUR_KATA_IS_ABOUT
```
- Output should be returned as a array of strings, e.g. ['Belgium', 'Germany', 'Venezuela', 'Romania']

If it's not public already, remember to change the visibility of your repository to public.
### Example Usage

### 🎫 Ticket 6 - Present you kata
- `filterFlag({hasStripes: true, hasCircles: true}, FULL_FLAG_LIST)` should return `['Argentina']` as this is the only flag with both stripes and a circle.
- `filterFlag({colours: ['red', 'yellow'], numberOfColors: 3}, FULL_FLAG_LIST)` should return `['Belgium', 'Germany', 'Venezuela', 'Romania']`.
- `filterFlag({hasStripes: false, numberOfColors: 2, stripeDirection: null}, FULL_FLAG_LIST)` should return `['China', 'European Union', 'Japan', 'Switzerland']`.

Make sure you present your project in [the markdown file here](/PROJECT_PRESENTATION.md) - this will be assessed alongside your actual kata. Treat this as an asynchronous presentation - anything you would want to talk through (plans, brainstorming, final results, user feedback, etc) should go in here.
### Evaluation Criteria

### 🎫 Ticket 7 - Complete katas from others
- Correctness: Your code must pass all test cases
- Input will never be null
- All input keys will have a corresponding value in the object FULL_FLAG_LIST

To solve katas created by other bootcampers, first clone their repository using the shared link. `cd` into the folder, run `npm install` to get the dependencies, then implement a solution in main.js. Execute their test cases to validate your code against their requirements. Provide feedback on the clarity of their instructions, difficulty level, and effectiveness of the tests. Engaging with each other's challenges allows everyone to learn. Make sure to critique respectfully - creating a programming challenge is difficult!
## Project Requirements

- Design a full suite of tests to evaluate the proposed solution against various input objects.
- Ensure the function meets all technical constraints and limitations.
- Provide clear and comprehensive documentation for users and contributors.
137 changes: 137 additions & 0 deletions flag_database.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
export const FULL_FLAG_LIST = Object.freeze([
{
country: "Argentina",
hasStripes: true,
numberOfColors: 3,
hasStars: false,
stripeDirection: "horizontal",
hasCircles: true, // The sun is a circle
colours: ["blue", "white", "yellow"],
},
{
country: "Canada",
hasStripes: true,
numberOfColors: 2,
hasStars: false,
stripeDirection: "vertical",
hasCircles: false,
colours: ["red", "white"],
},
{
country: "Belgium",
hasStripes: true,
numberOfColors: 3,
hasStars: false,
stripeDirection: "vertical",
hasCircles: false,
colours: ["black", "yellow", "red"],
},
{
country: "China",
hasStripes: false,
numberOfColors: 2,
hasStars: true,
stripeDirection: null, // No stripes
hasCircles: false,
colours: ["red", "yellow"],
},
{
country: "Australia",
hasStripes: false,
numberOfColors: 3,
hasStars: true,
stripeDirection: null, // No stripes
hasCircles: false,
colours: ["blue", "white", "red"],
},
{
country: "Germany",
hasStripes: true,
numberOfColors: 3,
hasStars: false,
stripeDirection: "horizontal",
hasCircles: false,
colours: ["black", "red", "yellow"],
},
{
country: "United States",
hasStripes: true,
numberOfColors: 3,
hasStars: true,
stripeDirection: "horizontal",
hasCircles: false,
colours: ["red", "white", "blue"],
},
{
country: "United Kingdom",
hasStripes: false,
numberOfColors: 3,
hasStars: false,
stripeDirection: null, // Cross pattern
hasCircles: false,
colours: ["red", "white", "blue"],
},
{
country: "Ukraine",
hasStripes: true,
numberOfColors: 2,
hasStars: false,
stripeDirection: "horizontal",
hasCircles: false,
colours: ["blue", "yellow"],
},
{
country: "Venezuela",
hasStripes: true,
numberOfColors: 3,
hasStars: true,
stripeDirection: "horizontal",
hasCircles: false,
colours: ["yellow", "blue", "red"],
},
{
country: "Netherlands",
hasStripes: true,
numberOfColors: 3,
hasStars: false,
stripeDirection: "horizontal",
hasCircles: false,
colours: ["red", "white", "blue"],
},
{
country: "European Union",
hasStripes: false,
numberOfColors: 2,
hasStars: true,
stripeDirection: null, // No stripes
hasCircles: false,
colours: ["blue", "yellow"],
},
{
country: "Japan",
hasStripes: false,
numberOfColors: 2,
hasStars: false,
stripeDirection: null, // No stripes
hasCircles: true, // Red circle
colours: ["white", "red"],
},
{
country: "Switzerland",
hasStripes: false,
numberOfColors: 2,
hasStars: false,
stripeDirection: null, // No stripes
hasCircles: false,
colours: ["red", "white"],
},
{
country: "Romania",
hasStripes: true,
numberOfColors: 3,
hasStars: false,
stripeDirection: "vertical",
hasCircles: false,
colours: ["blue", "yellow", "red"],
},
]);
40 changes: 40 additions & 0 deletions main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* Hello bootcampers!
*
* A career in tech brings with it countless advantages, not least of all being the flexible working arrangements that many roles offer us.
* However, being that we're all such big thinkers, sometimes smaller details of life evade us, such as:
* What did I eat for dinner last night? Where did I put my keys?...What country am I in again?...
*
* Imagine you've had one of these moments and all you've got to go off is a waving flag in front of you. Your challenge is to write a function that,
* when given some characteristics of the flag, interact with the provided flag 'library' (FULL_FLAG_LIST) and return the country/countries that you may be in!
*
* For reference, for each country held within the list, all details for that country's flag is stored in an object with the following keys:
*
* {
* country: string,
* hasStripes: boolean,
* numberOfColors: int,
* hasStars: boolean,
* stripeDirection: string, (can be "horizontal", "vertical" or null)
* hasCircles: boolean,
* colours: [string, string, string], (Can be an array containing varying number of strings)
* }
*
* A couple of extra notes for this challenge include:
* Any images of the sun is counted as a circle
* Flags with crosses (e.g. the UK) or no stripes will be marked as null
*
* Your function should handle input objects with varying sets of characteristics, and only return the names of the countries. You can assume that all provided attributes have corresponding entries in the FULL_FLAG_LIST object.
*
* A few examples:
* filterFlag({hasStripes: true, hasCircles: true},FULL_FLAG_LIST) should return ['Argentina'] as this is the only flag with both stripes and a circle
* filterFlag({colours: [ 'red', 'yellow' ], numberOfColors: 3}) should return [ 'Belgium', 'Germany', 'Venezuela', 'Romania']
* filterFlag({hasStripes: false, numberOfColors: 2, stripeDirection: null}) should return [ 'China', 'European Union', 'Japan', 'Switzerland' ])
*
* Best of luck!!
*/
export function filterFlag(searchTerms, fullFlagList) {
// Input your solution here!
}

// An input of hasStripes: true should equal ["Argentina","Canada","Belgium","Germany","United States","Ukraine","Venezuela","Netherlands","Romania
Loading