-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add a US scale for aid grades. It treats A# and C# as being part of the same scale, so that different grade contexts do not need to be assigned to neighbouring routes, e.g. if there is a grade with grade A2 next to a route with grade C1. Aid + mandatory free is not covered by this commit. Resolves: #79
- Loading branch information
Showing
11 changed files
with
263 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
Score,Aid | ||
0,A0 | ||
1,A0 | ||
2,A0 | ||
3,A0 | ||
4,A1 | ||
5,A1 | ||
6,A1 | ||
7,A1 | ||
8,A2 | ||
9,A2 | ||
10,A2 | ||
11,A2 | ||
12,A2+ | ||
13,A2+ | ||
14,A2+ | ||
15,A2+ | ||
16,A3 | ||
17,A3 | ||
18,A3 | ||
19,A3 | ||
20,A3+ | ||
21,A3+ | ||
22,A3+ | ||
23,A3+ | ||
24,A4 | ||
25,A4 | ||
26,A4 | ||
27,A4 | ||
28,A4+ | ||
29,A4+ | ||
30,A4+ | ||
31,A4+ | ||
32,A5 | ||
33,A5 | ||
34,A5 | ||
35,A5 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
[{"score":0,"aid":"A0"},{"score":1,"aid":"A0"},{"score":2,"aid":"A0"},{"score":3,"aid":"A0"},{"score":4,"aid":"A1"},{"score":5,"aid":"A1"},{"score":6,"aid":"A1"},{"score":7,"aid":"A1"},{"score":8,"aid":"A2"},{"score":9,"aid":"A2"},{"score":10,"aid":"A2"},{"score":11,"aid":"A2"},{"score":12,"aid":"A2+"},{"score":13,"aid":"A2+"},{"score":14,"aid":"A2+"},{"score":15,"aid":"A2+"},{"score":16,"aid":"A3"},{"score":17,"aid":"A3"},{"score":18,"aid":"A3"},{"score":19,"aid":"A3"},{"score":20,"aid":"A3+"},{"score":21,"aid":"A3+"},{"score":22,"aid":"A3+"},{"score":23,"aid":"A3+"},{"score":24,"aid":"A4"},{"score":25,"aid":"A4"},{"score":26,"aid":"A4"},{"score":27,"aid":"A4"},{"score":28,"aid":"A4+"},{"score":29,"aid":"A4+"},{"score":30,"aid":"A4+"},{"score":31,"aid":"A4+"},{"score":32,"aid":"A5"},{"score":33,"aid":"A5"},{"score":34,"aid":"A5"},{"score":35,"aid":"A5"}] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
import { Aid } from '../../scales' | ||
|
||
describe('Aid', () => { | ||
describe('Get Score', () => { | ||
describe('valid grade formats', () => { | ||
jest.spyOn(console, 'warn').mockImplementation() | ||
beforeEach(() => { | ||
jest.clearAllMocks() | ||
}) | ||
|
||
test('basic grade A', () => { | ||
const score = Aid.getScore('A0') | ||
expect(console.warn).not.toHaveBeenCalled() | ||
expect(score).not.toEqual(-1) | ||
}) | ||
|
||
test('basic grade C', () => { | ||
const score = Aid.getScore('C0') | ||
expect(console.warn).not.toHaveBeenCalled() | ||
expect(score).not.toEqual(-1) | ||
}) | ||
|
||
test('valid + modifier', () => { | ||
const score = Aid.getScore('A3+') | ||
expect(console.warn).not.toHaveBeenCalled() | ||
expect(score).not.toEqual(-1) | ||
}) | ||
|
||
test.failing('mandatory free', () => { | ||
const score = Aid.getScore('5.9 A0') | ||
expect(console.warn).not.toHaveBeenCalled() | ||
expect(score).not.toEqual(-1) | ||
}) | ||
}) | ||
|
||
describe('invalid grade formats', () => { | ||
jest.spyOn(console, 'warn').mockImplementation() | ||
beforeEach(() => { | ||
jest.clearAllMocks() | ||
}) | ||
|
||
test('A6 out of range', () => { | ||
const score = Aid.getScore('A6') | ||
expect(console.warn).toHaveBeenCalledWith('Unexpected grade format: A6 for grade scale Aid') | ||
expect(score).toEqual(-1) | ||
}) | ||
|
||
test('invalid minus modifier', () => { | ||
const score = Aid.getScore('A3-') | ||
expect(console.warn).toHaveBeenCalledWith('Unexpected grade format: A3- for grade scale Aid') | ||
expect(score).toEqual(-1) | ||
}) | ||
|
||
test('invalid plus modifier', () => { | ||
const score = Aid.getScore('A5+') | ||
expect(console.warn).toHaveBeenCalledWith('Unexpected grade format: A5+ for grade scale Aid') | ||
expect(score).toEqual(-1) | ||
}) | ||
|
||
test('plain YDS grade', () => { | ||
const score = Aid.getScore('5.9') | ||
expect(console.warn).toHaveBeenCalledWith('Unexpected grade format: 5.9 for grade scale Aid') | ||
expect(score).toEqual(-1) | ||
}) | ||
|
||
test('slash grade', () => { | ||
const score = Aid.getScore('A0/A1') | ||
expect(console.warn).toHaveBeenCalledWith('Unexpected grade format: A0/A1 for grade scale Aid') | ||
expect(score).toEqual(-1) | ||
}) | ||
|
||
test('not aid scale', () => { | ||
const score = Aid.getScore('v11') | ||
expect(console.warn).toHaveBeenCalledWith('Unexpected grade format: v11 for grade scale Aid') | ||
expect(score).toEqual(-1) | ||
}) | ||
}) | ||
|
||
describe('correct relative scores', () => { | ||
test('C0 = A0', () => { | ||
const aGrade = Aid.getScore('A0') | ||
const cGrade = Aid.getScore('C0') | ||
expect(cGrade).toEqual(aGrade) | ||
}) | ||
|
||
test('A3+ > A1', () => { | ||
const lowGrade = Aid.getScore('A1') | ||
const highGrade = Aid.getScore('A3+') | ||
expect(highGrade[0]).toBeGreaterThan(lowGrade[1]) | ||
}) | ||
|
||
test('A4 > A3+', () => { | ||
const lowGrade = Aid.getScore('A3+') | ||
const highGrade = Aid.getScore('A4') | ||
expect(highGrade[0]).toBeGreaterThan(lowGrade[1]) | ||
}) | ||
|
||
test('C4 > C3+', () => { | ||
const lowGrade = Aid.getScore('A3+') | ||
const highGrade = Aid.getScore('A4') | ||
expect(highGrade[0]).toBeGreaterThan(lowGrade[1]) | ||
}) | ||
|
||
test('C4 > A3+', () => { | ||
const lowGrade = Aid.getScore('A3+') | ||
const highGrade = Aid.getScore('A4') | ||
expect(highGrade[0]).toBeGreaterThan(lowGrade[1]) | ||
}) | ||
|
||
test('C5 = A5', () => { | ||
const aGrade = Aid.getScore('A5') | ||
const cGrade = Aid.getScore('C5') | ||
expect(cGrade).toEqual(aGrade) | ||
}) | ||
}) | ||
}) | ||
|
||
describe('Get Grade', () => { | ||
test('bottom of range', () => { | ||
expect(Aid.getGrade(0)).toBe('A0') | ||
}) | ||
|
||
test('top of range', () => { | ||
expect(Aid.getGrade(Infinity)).toBe('A5') | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import GradeScale, { findScoreRange, getAvgScore, GradeScales, Tuple } from '../GradeScale' | ||
import aid_table from '../data/aid.json' | ||
import { AidGrade } from '.' | ||
import { GradeBandTypes, routeScoreToBand } from '../GradeBands' | ||
|
||
// Supports [AC]0 -> [AC]5, with + grades on [AC]2 -> [AC]4 and no slash grades | ||
// https://en.wikipedia.org/wiki/Grade_(climbing)#Clean_scale | ||
const aidGradeRegex = /^([AC])([0-5]|[2-4]\+)$/i | ||
const isAid = (grade: string): RegExpMatchArray | null => grade.match(aidGradeRegex) | ||
|
||
const AidScale: GradeScale = { | ||
displayName: 'Aid Grade', | ||
name: GradeScales.AID, | ||
offset: 1000, | ||
allowableConversionType: [], | ||
isType: (grade: string): boolean => { | ||
if (isAid(grade) === null) { | ||
return false | ||
} | ||
return true | ||
}, | ||
getScore: (grade: string): number | Tuple => { | ||
return getScore(grade) | ||
}, | ||
getGrade: (score: number | Tuple): string => { | ||
const validateScore = (score: number): number => { | ||
const validScore = Number.isInteger(score) ? score : Math.ceil(score) | ||
return Math.min(Math.max(0, validScore), aid_table.length - 1) | ||
} | ||
|
||
if (typeof score === 'number') { | ||
return aid_table[validateScore(score)].aid | ||
} | ||
|
||
const low: string = aid_table[validateScore(score[0])].aid | ||
const high: string = aid_table[validateScore(score[1])].aid | ||
if (low === high) return low | ||
return `${low}/${high}` | ||
}, | ||
getGradeBand: (grade: string): GradeBandTypes => { | ||
const score = getScore(grade) | ||
return routeScoreToBand(getAvgScore(score)) | ||
} | ||
} | ||
|
||
const getScore = (grade: string): number | Tuple => { | ||
const parse = isAid(grade) | ||
if (parse == null) { | ||
console.warn(`Unexpected grade format: ${grade} for grade scale Aid`) | ||
return -1 | ||
} | ||
const [wholeMatch, AorC, gradeNum] = parse // eslint-disable-line @typescript-eslint/no-unused-vars | ||
|
||
const score = findScoreRange((r: AidGrade) => { | ||
return r.aid === ('A' + gradeNum) | ||
}, aid_table) | ||
|
||
return score | ||
} | ||
|
||
export default AidScale |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters