Skip to content

Commit

Permalink
feat: arithmetic sequence
Browse files Browse the repository at this point in the history
  • Loading branch information
iib0011 committed Mar 8, 2025
1 parent f678c76 commit a4895d6
Show file tree
Hide file tree
Showing 11 changed files with 249 additions and 48 deletions.
3 changes: 2 additions & 1 deletion .codebuddy/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
db/
db/
docs
44 changes: 24 additions & 20 deletions .idea/workspace.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 5 additions & 18 deletions src/components/ToolContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import ToolExamples, {
} from '@components/examples/ToolExamples';
import { ToolComponentProps } from '@tools/defineTool';

interface ToolContentPropsBase<T, I> extends ToolComponentProps {
interface ToolContentProps<T, I> extends ToolComponentProps {
// Input/Output components
inputComponent: ReactNode;
resultComponent: ReactNode;
Expand All @@ -29,28 +29,15 @@ interface ToolContentPropsBase<T, I> extends ToolComponentProps {
};

// Input value to pass to the compute function
input: I;
input?: I;

exampleCards?: CardExampleType<T>[];
setInput?: React.Dispatch<React.SetStateAction<I>>;

// Validation schema (optional)
validationSchema?: any;
}

interface ToolContentPropsWithExamples<T, I>
extends ToolContentPropsBase<T, I> {
exampleCards: CardExampleType<T>[];
setInput: React.Dispatch<React.SetStateAction<I>>;
}

interface ToolContentPropsWithoutExamples<T, I>
extends ToolContentPropsBase<T, I> {
exampleCards?: never;
setInput?: never;
}

type ToolContentProps<T, I> =
| ToolContentPropsWithExamples<T, I>
| ToolContentPropsWithoutExamples<T, I>;

export default function ToolContent<T extends FormikValues, I>({
title,
inputComponent,
Expand Down
4 changes: 2 additions & 2 deletions src/components/examples/ExampleCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ import { GetGroupsType } from '@components/options/ToolOptions';
export interface ExampleCardProps<T> {
title: string;
description: string;
sampleText: string;
sampleText?: string;
sampleResult: string;
sampleOptions: T;
changeInputResult: (newInput: string, newOptions: T) => void;
changeInputResult: (newInput: string | undefined, newOptions: T) => void;
getGroups: GetGroupsType<T> | null;
}

Expand Down
6 changes: 3 additions & 3 deletions src/components/examples/ToolExamples.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export interface ExampleProps<T> {
exampleCards: CardExampleType<T>[];
getGroups: GetGroupsType<T> | null;
formRef: React.RefObject<FormikProps<T>>;
setInput: React.Dispatch<React.SetStateAction<any>>;
setInput?: React.Dispatch<React.SetStateAction<any>>;
}

export default function ToolExamples<T>({
Expand All @@ -26,8 +26,8 @@ export default function ToolExamples<T>({
formRef,
setInput
}: ExampleProps<T>) {
function changeInputResult(newInput: string, newOptions: T) {
setInput(newInput);
function changeInputResult(newInput: string | undefined, newOptions: T) {
setInput?.(newInput);
formRef.current?.setValues(newOptions);
const toolsElement = document.getElementById('tool');
if (toolsElement) {
Expand Down
15 changes: 12 additions & 3 deletions src/pages/tools/json/stringify/meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,18 @@ import { lazy } from 'react';
export const tool = defineTool('json', {
name: 'Stringify JSON',
path: 'stringify',
icon: 'lets-icons:json-format-light',
description: 'Convert JavaScript objects and arrays into their JSON string representation. Options include custom indentation and HTML character escaping for web-safe JSON strings.',
icon: 'ant-design:field-string-outlined',
description:
'Convert JavaScript objects and arrays into their JSON string representation. Options include custom indentation and HTML character escaping for web-safe JSON strings.',
shortDescription: 'Convert JavaScript objects to JSON strings',
keywords: ['stringify', 'serialize', 'convert', 'object', 'array', 'json', 'string'],
keywords: [
'stringify',
'serialize',
'convert',
'object',
'array',
'json',
'string'
],
component: lazy(() => import('./index'))
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { describe, expect, it } from 'vitest';
import { generateArithmeticSequence } from './service';

describe('generateArithmeticSequence', () => {
it('should generate basic arithmetic sequence', () => {
const result = generateArithmeticSequence(1, 2, 5, ', ');
expect(result).toBe('1, 3, 5, 7, 9');
});

it('should handle negative first term', () => {
const result = generateArithmeticSequence(-5, 2, 5, ' ');
expect(result).toBe('-5 -3 -1 1 3');
});

it('should handle negative common difference', () => {
const result = generateArithmeticSequence(10, -2, 5, ',');
expect(result).toBe('10,8,6,4,2');
});

it('should handle decimal numbers', () => {
const result = generateArithmeticSequence(1.5, 0.5, 4, ' ');
expect(result).toBe('1.5 2 2.5 3');
});

it('should handle single term sequence', () => {
const result = generateArithmeticSequence(1, 2, 1, ',');
expect(result).toBe('1');
});
});
136 changes: 136 additions & 0 deletions src/pages/tools/number/arithmetic-sequence/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
import { Box } from '@mui/material';
import React, { useState } from 'react';
import ToolContent from '@components/ToolContent';
import ToolTextResult from '@components/result/ToolTextResult';
import TextFieldWithDesc from '@components/options/TextFieldWithDesc';
import { generateArithmeticSequence } from './service';
import * as Yup from 'yup';
import { CardExampleType } from '@components/examples/ToolExamples';

type InitialValuesType = {
firstTerm: string;
commonDifference: string;
numberOfTerms: string;
separator: string;
};

const initialValues: InitialValuesType = {
firstTerm: '1',
commonDifference: '2',
numberOfTerms: '10',
separator: ', '
};

const validationSchema = Yup.object({
firstTerm: Yup.number().required('First term is required'),
commonDifference: Yup.number().required('Common difference is required'),
numberOfTerms: Yup.number()
.min(1, 'Must generate at least 1 term')
.max(1000, 'Maximum 1000 terms allowed')
.required('Number of terms is required'),
separator: Yup.string().required('Separator is required')
});

const exampleCards: CardExampleType<InitialValuesType>[] = [
{
title: 'Basic Arithmetic Sequence',
description:
'Generate a sequence starting at 1, increasing by 2, for 5 terms',
sampleOptions: {
firstTerm: '1',
commonDifference: '2',
numberOfTerms: '5',
separator: ', '
},
sampleResult: '1, 3, 5, 7, 9'
},
{
title: 'Negative Sequence',
description: 'Generate a decreasing sequence starting at 10',
sampleOptions: {
firstTerm: '10',
commonDifference: '-3',
numberOfTerms: '4',
separator: ' → '
},
sampleResult: '10 → 7 → 4 → 1'
},
{
title: 'Decimal Sequence',
description: 'Generate a sequence with decimal numbers',
sampleOptions: {
firstTerm: '0.5',
commonDifference: '0.5',
numberOfTerms: '6',
separator: ' '
},
sampleResult: '0.5 1 1.5 2 2.5 3'
}
];

export default function ArithmeticSequence() {
const [result, setResult] = useState<string>('');

return (
<ToolContent
inputComponent={null}
resultComponent={
<ToolTextResult title="Generated Sequence" value={result} />
}
initialValues={initialValues}
validationSchema={validationSchema}
exampleCards={exampleCards}
toolInfo={{
title: 'What is an Arithmetic Sequence?',
description:
'An arithmetic sequence is a sequence of numbers where the difference between each consecutive term is constant. This constant difference is called the common difference. Given the first term (a₁) and the common difference (d), each term can be found by adding the common difference to the previous term.'
}}
getGroups={({ values, updateField }) => [
{
title: 'Sequence Parameters',
component: (
<Box>
<TextFieldWithDesc
description="First term of the sequence (a₁)"
value={values.firstTerm}
onOwnChange={(val) => updateField('firstTerm', val)}
type="number"
/>
<TextFieldWithDesc
description="Common difference between terms (d)"
value={values.commonDifference}
onOwnChange={(val) => updateField('commonDifference', val)}
type="number"
/>
<TextFieldWithDesc
description="Number of terms to generate (n)"
value={values.numberOfTerms}
onOwnChange={(val) => updateField('numberOfTerms', val)}
type="number"
/>
</Box>
)
},
{
title: 'Output Format',
component: (
<TextFieldWithDesc
description="Separator between terms"
value={values.separator}
onOwnChange={(val) => updateField('separator', val)}
/>
)
}
]}
compute={(values) => {
const sequence = generateArithmeticSequence(
Number(values.firstTerm),
Number(values.commonDifference),
Number(values.numberOfTerms),
values.separator
);
setResult(sequence);
}}
/>
);
}
21 changes: 21 additions & 0 deletions src/pages/tools/number/arithmetic-sequence/meta.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { defineTool } from '@tools/defineTool';
import { lazy } from 'react';

export const tool = defineTool('number', {
name: 'Generate Arithmetic Sequence',
path: 'arithmetic-sequence',
icon: 'ic:sharp-plus',
description:
'Generate an arithmetic sequence by specifying the first term (a₁), common difference (d), and number of terms (n). The tool creates a sequence where each number differs from the previous by a constant difference.',
shortDescription:
'Generate a sequence where each term differs by a constant value.',
keywords: [
'arithmetic',
'sequence',
'progression',
'numbers',
'series',
'generate'
],
component: lazy(() => import('./index'))
});
13 changes: 13 additions & 0 deletions src/pages/tools/number/arithmetic-sequence/service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export function generateArithmeticSequence(
firstTerm: number,
commonDifference: number,
numberOfTerms: number,
separator: string
): string {
const sequence: number[] = [];
for (let i = 0; i < numberOfTerms; i++) {
const term = firstTerm + i * commonDifference;
sequence.push(term);
}
return sequence.join(separator);
}
3 changes: 2 additions & 1 deletion src/pages/tools/number/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { tool as numberSum } from './sum/meta';
import { tool as numberGenerate } from './generate/meta';
import { tool as numberArithmeticSequence } from './arithmetic-sequence/meta';

export const numberTools = [numberSum, numberGenerate];
export const numberTools = [numberSum, numberGenerate, numberArithmeticSequence];

0 comments on commit a4895d6

Please sign in to comment.