Velocicode 0.5.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. velocicode/__init__.py +0 -0
  2. velocicode/benchmarks/fibonacci/cpp/main.cpp +16 -0
  3. velocicode/benchmarks/fibonacci/go/main.go +25 -0
  4. velocicode/benchmarks/fibonacci/javascript/main.js +9 -0
  5. velocicode/benchmarks/fibonacci/python/main.py +12 -0
  6. velocicode/benchmarks/fibonacci/rust/main.rs +18 -0
  7. velocicode/benchmarks/matrix_mul/cpp/main.cpp +41 -0
  8. velocicode/benchmarks/matrix_mul/go/main.go +49 -0
  9. velocicode/benchmarks/matrix_mul/javascript/main.js +31 -0
  10. velocicode/benchmarks/matrix_mul/python/main.py +25 -0
  11. velocicode/benchmarks/matrix_mul/rust/main.rs +37 -0
  12. velocicode/benchmarks/primes/cpp/main.cpp +28 -0
  13. velocicode/benchmarks/primes/go/main.go +40 -0
  14. velocicode/benchmarks/primes/javascript/main.js +20 -0
  15. velocicode/benchmarks/primes/python/main.py +24 -0
  16. velocicode/benchmarks/primes/rust/main.rs +35 -0
  17. velocicode/benchmarks/quicksort/cpp/main.cpp +24 -0
  18. velocicode/benchmarks/quicksort/go/main.go +26 -0
  19. velocicode/benchmarks/quicksort/javascript/main.js +11 -0
  20. velocicode/benchmarks/quicksort/python/main.py +26 -0
  21. velocicode/benchmarks/quicksort/rust/main.rs +40 -0
  22. velocicode/config.yaml +16 -0
  23. velocicode/main.py +239 -0
  24. velocicode/report_generator.py +143 -0
  25. velocicode/reporter.py +79 -0
  26. velocicode/runner.py +65 -0
  27. velocicode/system_info.py +23 -0
  28. velocicode-0.5.0.dist-info/METADATA +92 -0
  29. velocicode-0.5.0.dist-info/RECORD +33 -0
  30. velocicode-0.5.0.dist-info/WHEEL +5 -0
  31. velocicode-0.5.0.dist-info/entry_points.txt +2 -0
  32. velocicode-0.5.0.dist-info/licenses/LICENSE +21 -0
  33. velocicode-0.5.0.dist-info/top_level.txt +1 -0
velocicode/__init__.py ADDED
File without changes
@@ -0,0 +1,16 @@
1
+ #include <iostream>
2
+ #include <cstdlib>
3
+
4
+ int fib(int n) {
5
+ if (n <= 1) return n;
6
+ return fib(n - 1) + fib(n - 2);
7
+ }
8
+
9
+ int main(int argc, char* argv[]) {
10
+ int n = 35;
11
+ if (argc > 1) {
12
+ n = std::atoi(argv[1]);
13
+ }
14
+ std::cout << fib(n) << std::endl;
15
+ return 0;
16
+ }
@@ -0,0 +1,25 @@
1
+ package main
2
+
3
+ import (
4
+ "fmt"
5
+ "os"
6
+ "strconv"
7
+ )
8
+
9
+ func fib(n int) int {
10
+ if n <= 1 {
11
+ return n
12
+ }
13
+ return fib(n-1) + fib(n-2)
14
+ }
15
+
16
+ func main() {
17
+ n := 35
18
+ if len(os.Args) > 1 {
19
+ val, err := strconv.Atoi(os.Args[1])
20
+ if err == nil {
21
+ n = val
22
+ }
23
+ }
24
+ fmt.Println(fib(n))
25
+ }
@@ -0,0 +1,9 @@
1
+ function fib(n) {
2
+ if (n <= 1) return n;
3
+ return fib(n - 1) + fib(n - 2);
4
+ }
5
+
6
+ const args = process.argv.slice(2);
7
+ const n = args.length > 0 ? parseInt(args[0]) : 35;
8
+
9
+ console.log(fib(n));
@@ -0,0 +1,12 @@
1
+ import sys
2
+
3
+ def fib(n):
4
+ if n <= 1:
5
+ return n
6
+ return fib(n - 1) + fib(n - 2)
7
+
8
+ if __name__ == "__main__":
9
+ n = 35
10
+ if len(sys.argv) > 1:
11
+ n = int(sys.argv[1])
12
+ print(fib(n))
@@ -0,0 +1,18 @@
1
+ use std::env;
2
+
3
+ fn fib(n: u32) -> u32 {
4
+ if n <= 1 {
5
+ return n;
6
+ }
7
+ fib(n - 1) + fib(n - 2)
8
+ }
9
+
10
+ fn main() {
11
+ let args: Vec<String> = env::args().collect();
12
+ let n = if args.len() > 1 {
13
+ args[1].parse().unwrap_or(35)
14
+ } else {
15
+ 35
16
+ };
17
+ println!("{}", fib(n));
18
+ }
@@ -0,0 +1,41 @@
1
+ #include <iostream>
2
+ #include <vector>
3
+ #include <cstdlib>
4
+ #include <random>
5
+
6
+ using namespace std;
7
+
8
+ vector<vector<double>> generate_matrix(int n) {
9
+ vector<vector<double>> m(n, vector<double>(n));
10
+ random_device rd;
11
+ mt19937 gen(rd());
12
+ uniform_real_distribution<> dis(0.0, 1.0);
13
+ for(int i=0; i<n; ++i)
14
+ for(int j=0; j<n; ++j)
15
+ m[i][j] = dis(gen);
16
+ return m;
17
+ }
18
+
19
+ vector<vector<double>> mat_mul(const vector<vector<double>>& A, const vector<vector<double>>& B, int n) {
20
+ vector<vector<double>> C(n, vector<double>(n, 0.0));
21
+ for (int i = 0; i < n; ++i) {
22
+ for (int k = 0; k < n; ++k) {
23
+ for (int j = 0; j < n; ++j) {
24
+ C[i][j] += A[i][k] * B[k][j];
25
+ }
26
+ }
27
+ }
28
+ return C;
29
+ }
30
+
31
+ int main(int argc, char* argv[]) {
32
+ int n = 200;
33
+ if (argc > 1) n = atoi(argv[1]);
34
+
35
+ auto A = generate_matrix(n);
36
+ auto B = generate_matrix(n);
37
+ auto C = mat_mul(A, B, n);
38
+
39
+ cout << C[0][0] << endl;
40
+ return 0;
41
+ }
@@ -0,0 +1,49 @@
1
+ package main
2
+
3
+ import (
4
+ "fmt"
5
+ "math/rand"
6
+ "os"
7
+ "strconv"
8
+ )
9
+
10
+ func generateMatrix(n int) [][]float64 {
11
+ m := make([][]float64, n)
12
+ for i := range m {
13
+ m[i] = make([]float64, n)
14
+ for j := range m[i] {
15
+ m[i][j] = rand.Float64()
16
+ }
17
+ }
18
+ return m
19
+ }
20
+
21
+ func matMul(a, b [][]float64, n int) [][]float64 {
22
+ c := make([][]float64, n)
23
+ for i := range c {
24
+ c[i] = make([]float64, n)
25
+ }
26
+
27
+ for i := 0; i < n; i++ {
28
+ for k := 0; k < n; k++ {
29
+ for j := 0; j < n; j++ {
30
+ c[i][j] += a[i][k] * b[k][j]
31
+ }
32
+ }
33
+ }
34
+ return c
35
+ }
36
+
37
+ func main() {
38
+ n := 200
39
+ if len(os.Args) > 1 {
40
+ if val, err := strconv.Atoi(os.Args[1]); err == nil {
41
+ n = val
42
+ }
43
+ }
44
+
45
+ a := generateMatrix(n)
46
+ b := generateMatrix(n)
47
+ c := matMul(a, b, n)
48
+ fmt.Println(c[0][0])
49
+ }
@@ -0,0 +1,31 @@
1
+ function generateMatrix(n) {
2
+ const m = [];
3
+ for (let i = 0; i < n; i++) {
4
+ m[i] = [];
5
+ for (let j = 0; j < n; j++) {
6
+ m[i][j] = Math.random();
7
+ }
8
+ }
9
+ return m;
10
+ }
11
+
12
+ function matMul(A, B, n) {
13
+ const C = [];
14
+ for (let i = 0; i < n; i++) {
15
+ C[i] = new Float64Array(n);
16
+ for (let k = 0; k < n; k++) {
17
+ for (let j = 0; j < n; j++) {
18
+ C[i][j] += A[i][k] * B[k][j];
19
+ }
20
+ }
21
+ }
22
+ return C;
23
+ }
24
+
25
+ const args = process.argv.slice(2);
26
+ const n = args.length > 0 ? parseInt(args[0]) : 200;
27
+
28
+ const A = generateMatrix(n);
29
+ const B = generateMatrix(n);
30
+ const C = matMul(A, B, n);
31
+ console.log(C[0][0]);
@@ -0,0 +1,25 @@
1
+ import sys
2
+ import random
3
+
4
+ def generate_matrix(n):
5
+ return [[random.random() for _ in range(n)] for _ in range(n)]
6
+
7
+ def mat_mul(A, B, n):
8
+ C = [[0] * n for _ in range(n)]
9
+ for i in range(n):
10
+ for j in range(n):
11
+ sum_val = 0
12
+ for k in range(n):
13
+ sum_val += A[i][k] * B[k][j]
14
+ C[i][j] = sum_val
15
+ return C
16
+
17
+ if __name__ == "__main__":
18
+ n = 200
19
+ if len(sys.argv) > 1:
20
+ n = int(sys.argv[1])
21
+
22
+ A = generate_matrix(n)
23
+ B = generate_matrix(n)
24
+ C = mat_mul(A, B, n)
25
+ print(C[0][0]) # prevent optimization
@@ -0,0 +1,37 @@
1
+ use std::env;
2
+
3
+ fn generate_matrix(n: usize) -> Vec<Vec<f64>> {
4
+ let mut m = vec![vec![0.0; n]; n];
5
+ for i in 0..n {
6
+ for j in 0..n {
7
+ m[i][j] = (i as f64 + j as f64) * 0.001; // Simple deterministic generation
8
+ }
9
+ }
10
+ m
11
+ }
12
+
13
+ fn mat_mul(a: &Vec<Vec<f64>>, b: &Vec<Vec<f64>>, n: usize) -> Vec<Vec<f64>> {
14
+ let mut c = vec![vec![0.0; n]; n];
15
+ for i in 0..n {
16
+ for k in 0..n {
17
+ for j in 0..n {
18
+ c[i][j] += a[i][k] * b[k][j];
19
+ }
20
+ }
21
+ }
22
+ c
23
+ }
24
+
25
+ fn main() {
26
+ let args: Vec<String> = env::args().collect();
27
+ let n = if args.len() > 1 {
28
+ args[1].parse().unwrap_or(200)
29
+ } else {
30
+ 200
31
+ };
32
+
33
+ let a = generate_matrix(n);
34
+ let b = generate_matrix(n);
35
+ let c = mat_mul(&a, &b, n);
36
+ println!("{}", c[0][0]);
37
+ }
@@ -0,0 +1,28 @@
1
+ #include <iostream>
2
+ #include <vector>
3
+ #include <cstdlib>
4
+
5
+ using namespace std;
6
+
7
+ int sieve(int n) {
8
+ vector<bool> primes(n + 1, true);
9
+ for (int p = 2; p * p <= n; p++) {
10
+ if (primes[p] == true) {
11
+ for (int i = p * p; i <= n; i += p)
12
+ primes[i] = false;
13
+ }
14
+ }
15
+
16
+ int count = 0;
17
+ for (int p = 2; p <= n; p++)
18
+ if (primes[p]) count++;
19
+ return count;
20
+ }
21
+
22
+ int main(int argc, char* argv[]) {
23
+ int n = 1000000;
24
+ if (argc > 1) n = atoi(argv[1]);
25
+
26
+ cout << sieve(n) << endl;
27
+ return 0;
28
+ }
@@ -0,0 +1,40 @@
1
+ package main
2
+
3
+ import (
4
+ "fmt"
5
+ "os"
6
+ "strconv"
7
+ )
8
+
9
+ func sieve(n int) int {
10
+ primes := make([]bool, n+1)
11
+ for i := 0; i <= n; i++ {
12
+ primes[i] = true
13
+ }
14
+
15
+ for p := 2; p*p <= n; p++ {
16
+ if primes[p] == true {
17
+ for i := p * p; i <= n; i += p {
18
+ primes[i] = false
19
+ }
20
+ }
21
+ }
22
+
23
+ count := 0
24
+ for p := 2; p <= n; p++ {
25
+ if primes[p] {
26
+ count++
27
+ }
28
+ }
29
+ return count
30
+ }
31
+
32
+ func main() {
33
+ n := 1000000
34
+ if len(os.Args) > 1 {
35
+ if val, err := strconv.Atoi(os.Args[1]); err == nil {
36
+ n = val
37
+ }
38
+ }
39
+ fmt.Println(sieve(n))
40
+ }
@@ -0,0 +1,20 @@
1
+ function sieve(n) {
2
+ const primes = new Uint8Array(n + 1).fill(1);
3
+
4
+ for (let p = 2; p * p <= n; p++) {
5
+ if (primes[p] === 1) {
6
+ for (let i = p * p; i <= n; i += p)
7
+ primes[i] = 0;
8
+ }
9
+ }
10
+
11
+ let count = 0;
12
+ for (let p = 2; p <= n; p++)
13
+ if (primes[p] === 1) count++;
14
+ return count;
15
+ }
16
+
17
+ const args = process.argv.slice(2);
18
+ const n = args.length > 0 ? parseInt(args[0]) : 1000000;
19
+
20
+ console.log(sieve(n));
@@ -0,0 +1,24 @@
1
+ import sys
2
+
3
+ def sieve(n):
4
+ primes = [True] * (n + 1)
5
+ p = 2
6
+ while (p * p <= n):
7
+ if (primes[p] == True):
8
+ for i in range(p * p, n + 1, p):
9
+ primes[i] = False
10
+ p += 1
11
+
12
+ # Count primes
13
+ count = 0
14
+ for p in range(2, n + 1):
15
+ if primes[p]:
16
+ count += 1
17
+ return count
18
+
19
+ if __name__ == "__main__":
20
+ n = 1000000
21
+ if len(sys.argv) > 1:
22
+ n = int(sys.argv[1])
23
+
24
+ print(sieve(n))
@@ -0,0 +1,35 @@
1
+ use std::env;
2
+
3
+ fn sieve(n: usize) -> i32 {
4
+ let mut primes = vec![true; n + 1];
5
+ let mut p = 2;
6
+ while p * p <= n {
7
+ if primes[p] {
8
+ let mut i = p * p;
9
+ while i <= n {
10
+ primes[i] = false;
11
+ i += p;
12
+ }
13
+ }
14
+ p += 1;
15
+ }
16
+
17
+ let mut count = 0;
18
+ for p in 2..=n {
19
+ if primes[p] {
20
+ count += 1;
21
+ }
22
+ }
23
+ count
24
+ }
25
+
26
+ fn main() {
27
+ let args: Vec<String> = env::args().collect();
28
+ let n = if args.len() > 1 {
29
+ args[1].parse().unwrap_or(1000000)
30
+ } else {
31
+ 1000000
32
+ };
33
+
34
+ println!("{}", sieve(n));
35
+ }
@@ -0,0 +1,24 @@
1
+ #include <iostream>
2
+ #include <vector>
3
+ #include <cstdlib>
4
+ #include <algorithm>
5
+ #include <random>
6
+
7
+ using namespace std;
8
+
9
+ int main(int argc, char* argv[]) {
10
+ int n = 1000000;
11
+ if (argc > 1) n = atoi(argv[1]);
12
+
13
+ vector<int> data(n);
14
+ random_device rd;
15
+ mt19937 gen(rd());
16
+ uniform_int_distribution<> dis(0, 1000000);
17
+
18
+ for(int i=0; i<n; ++i) data[i] = dis(gen);
19
+
20
+ sort(data.begin(), data.end());
21
+
22
+ cout << data[0] << endl;
23
+ return 0;
24
+ }
@@ -0,0 +1,26 @@
1
+ package main
2
+
3
+ import (
4
+ "fmt"
5
+ "math/rand"
6
+ "os"
7
+ "sort"
8
+ "strconv"
9
+ )
10
+
11
+ func main() {
12
+ n := 1000000
13
+ if len(os.Args) > 1 {
14
+ if val, err := strconv.Atoi(os.Args[1]); err == nil {
15
+ n = val
16
+ }
17
+ }
18
+
19
+ data := make([]int, n)
20
+ for i := 0; i < n; i++ {
21
+ data[i] = rand.Intn(1000000)
22
+ }
23
+
24
+ sort.Ints(data)
25
+ fmt.Println(data[0])
26
+ }
@@ -0,0 +1,11 @@
1
+ const args = process.argv.slice(2);
2
+ const n = args.length > 0 ? parseInt(args[0]) : 1000000;
3
+
4
+ const data = new Int32Array(n);
5
+ for (let i = 0; i < n; i++) {
6
+ data[i] = Math.floor(Math.random() * 1000000);
7
+ }
8
+
9
+ data.sort();
10
+
11
+ console.log(data[0]);
@@ -0,0 +1,26 @@
1
+ import sys
2
+ import random
3
+ import time
4
+
5
+ sys.setrecursionlimit(2000000)
6
+
7
+ def quick_sort(arr):
8
+ if len(arr) <= 1:
9
+ return arr
10
+ pivot = arr[len(arr) // 2]
11
+ left = [x for x in arr if x < pivot]
12
+ middle = [x for x in arr if x == pivot]
13
+ right = [x for x in arr if x > pivot]
14
+ return quick_sort(left) + middle + quick_sort(right)
15
+
16
+ if __name__ == "__main__":
17
+ n = 1000000
18
+ if len(sys.argv) > 1:
19
+ n = int(sys.argv[1])
20
+
21
+ # Generate random data
22
+ data = [random.randint(0, 1000000) for _ in range(n)]
23
+
24
+ sorted_data = quick_sort(data)
25
+ # Print first element to prevent optimization
26
+ print(sorted_data[0])
@@ -0,0 +1,40 @@
1
+ use std::env;
2
+
3
+ struct Lcg {
4
+ state: u64,
5
+ }
6
+
7
+ impl Lcg {
8
+ fn new(seed: u64) -> Self {
9
+ Lcg { state: seed }
10
+ }
11
+
12
+ fn next(&mut self) -> u32 {
13
+ // Linear Congruential Generator config (same as glibc's rand)
14
+ self.state = (self.state.wrapping_mul(1103515245).wrapping_add(12345)) % 2147483648;
15
+ self.state as u32
16
+ }
17
+
18
+ fn gen_range(&mut self, range: std::ops::Range<i32>) -> i32 {
19
+ let min = range.start;
20
+ let max = range.end;
21
+ let width = (max - min) as u32;
22
+ (self.next() % width) as i32 + min
23
+ }
24
+ }
25
+
26
+ fn main() {
27
+ let args: Vec<String> = env::args().collect();
28
+ let n = if args.len() > 1 {
29
+ args[1].parse().unwrap_or(1000000)
30
+ } else {
31
+ 1000000
32
+ };
33
+
34
+ let mut rng = Lcg::new(12345);
35
+ let mut data: Vec<i32> = (0..n).map(|_| rng.gen_range(0..1000000)).collect();
36
+
37
+ data.sort();
38
+
39
+ println!("{}", data[0]);
40
+ }
velocicode/config.yaml ADDED
@@ -0,0 +1,16 @@
1
+ languages:
2
+ python:
3
+ run: "python3 {source}"
4
+ cpp:
5
+ compile: "g++ -O3 -std=c++11 {source} -o {out}"
6
+ run: "{out}"
7
+ rust:
8
+ compile: "rustc -O {source} -o {out}"
9
+ run: "{out}"
10
+ javascript:
11
+ run: "node {source}"
12
+ go:
13
+ compile: "go build -o {out} {source}"
14
+ run: "{out}"
15
+ dependencies:
16
+ rust: [rand]
velocicode/main.py ADDED
@@ -0,0 +1,239 @@
1
+ import argparse
2
+ import yaml
3
+ import os
4
+ import sys
5
+ from glob import glob
6
+ import shutil
7
+ from .runner import BenchmarkRunner
8
+ from .reporter import print_table
9
+ from .system_info import get_system_info
10
+ from rich.console import Console
11
+ from rich.panel import Panel
12
+ from rich.prompt import Confirm
13
+ from rich.progress import Progress, SpinnerColumn, TextColumn
14
+ from rich import print as rprint
15
+
16
+ console = Console()
17
+
18
+ def check_dependencies(config, verbose=True):
19
+ if verbose:
20
+ rprint(Panel("Checking System Dependencies", style="bold blue"))
21
+
22
+ languages = config.get('languages', {})
23
+ valid_langs = set()
24
+ missing_langs = set()
25
+
26
+ for lang, cfg in languages.items():
27
+ # Determine the command to check
28
+ # If 'compile' exists, check the compiler. Else check 'run'.
29
+ cmd_str = cfg.get('compile') or cfg.get('run')
30
+ if not cmd_str:
31
+ if verbose:
32
+ rprint(f"[yellow]WARN[/yellow] {lang}: No command defined")
33
+ continue
34
+
35
+ # simpler parsing: assume command is the first word
36
+ program = cmd_str.split()[0]
37
+
38
+ path = shutil.which(program)
39
+ if path:
40
+ if verbose:
41
+ rprint(f"[green]✔[/green] {lang:<12} (Found: [cyan]{program}[/cyan])")
42
+ valid_langs.add(lang)
43
+ else:
44
+ if verbose:
45
+ rprint(f"[red]✘[/red] {lang:<12} (Missing: [bold]{program}[/bold])")
46
+ missing_langs.add(lang)
47
+
48
+ return valid_langs, missing_langs
49
+
50
+
51
+ def get_base_dir():
52
+ return os.path.dirname(os.path.abspath(__file__))
53
+
54
+ def load_config():
55
+ path = os.path.join(get_base_dir(), "config.yaml")
56
+ if not os.path.exists(path):
57
+ print(f"Config file not found: {path}")
58
+ sys.exit(1)
59
+ with open(path, 'r') as f:
60
+ return yaml.safe_load(f)
61
+
62
+ def discover_benchmarks():
63
+ base_dir = os.path.join(get_base_dir(), "benchmarks")
64
+ # Structure: benchmarks/<algo>/<lang>/<file>
65
+ # We want to find all <algo> directories
66
+ if not os.path.exists(base_dir):
67
+ return []
68
+ return [d for d in os.listdir(base_dir) if os.path.isdir(os.path.join(base_dir, d))]
69
+
70
+ def main():
71
+ parser = argparse.ArgumentParser(description="Velocicode - Programming Language Speed Benchmark Tool")
72
+ parser.add_argument("action", choices=["run", "list", "check"], help="Action to perform")
73
+ parser.add_argument("--filter-algo", help="Filter by specific algorithm name")
74
+ parser.add_argument("--filter-lang", help="Filter by specific languages (comma separated)")
75
+ parser.add_argument("--iter", type=int, default=5, help="Number of iterations per benchmark")
76
+ parser.add_argument("--json", help="Export results to a JSON file")
77
+ parser.add_argument("--html", help="Export results to an interactive HTML report")
78
+
79
+ args = parser.parse_args()
80
+
81
+ config = load_config()
82
+
83
+ if args.action == "check":
84
+ check_dependencies(config)
85
+ return
86
+
87
+ runner = BenchmarkRunner(config)
88
+
89
+ algos = discover_benchmarks()
90
+ if args.filter_algo:
91
+ algos = [a for a in algos if a == args.filter_algo]
92
+
93
+ target_langs = None
94
+ if args.filter_lang:
95
+ target_langs = args.filter_lang.split(',')
96
+
97
+ results = []
98
+
99
+ if args.action == "list":
100
+ print("Available benchmarks:")
101
+ for a in algos:
102
+ print(f" - {a}")
103
+ return
104
+
105
+ if args.action == "run":
106
+ # 1. Display System Info
107
+ sys_info = get_system_info()
108
+ info_text = f"""
109
+ [bold]OS:[/bold] {sys_info['os']}
110
+ [bold]CPU:[/bold] {sys_info['cpu']}
111
+ [bold]Arch:[/bold] {sys_info['arch']}
112
+ [bold]RAM:[/bold] {sys_info['ram']}
113
+ """
114
+ rprint(Panel(info_text.strip(), title="System Information", border_style="green"))
115
+
116
+ # 2. Check Dependencies
117
+ valid_langs, missing_langs = check_dependencies(config, verbose=False)
118
+
119
+ if missing_langs:
120
+ rprint(f"[yellow]Warning: The following languages are missing:[/yellow] [bold]{', '.join(missing_langs)}[/bold]")
121
+ if not Confirm.ask("Do you want to continue running valid languages only?"):
122
+ rprint("[red]Aborted.[/red]")
123
+ return
124
+
125
+ base_dir = os.path.join(get_base_dir(), "benchmarks")
126
+
127
+ # Collect all tasks first
128
+ tasks_to_run = []
129
+ for algo in algos:
130
+ algo_dir = os.path.join(base_dir, algo)
131
+ lang_dirs = [d for d in os.listdir(algo_dir) if os.path.isdir(os.path.join(algo_dir, d)) and d != 'bin']
132
+
133
+ for lang in lang_dirs:
134
+ if target_langs and lang not in target_langs:
135
+ continue
136
+
137
+ # SKIP if missing
138
+ if lang in missing_langs:
139
+ continue
140
+
141
+ ext_map = {
142
+ 'python': 'main.py',
143
+ 'cpp': 'main.cpp',
144
+ 'rust': 'main.rs',
145
+ 'go': 'main.go',
146
+ 'javascript': 'main.js'
147
+ }
148
+ expected_file = ext_map.get(lang)
149
+ if not expected_file:
150
+ continue
151
+ full_path = os.path.join(algo_dir, lang, expected_file)
152
+ if not os.path.exists(full_path):
153
+ continue
154
+ tasks_to_run.append((algo, lang, full_path))
155
+
156
+ if not tasks_to_run:
157
+ rprint("[yellow]No benchmarks found to run.[/yellow]")
158
+ return
159
+
160
+ with Progress(
161
+ SpinnerColumn(),
162
+ TextColumn("[progress.description]{task.description}"),
163
+ transient=True
164
+ ) as progress:
165
+ for algo, lang, full_path in tasks_to_run:
166
+ # Initial task description
167
+ desc_tpl = f"[bold cyan]{algo}[/bold cyan] ([magenta]{lang}[/magenta])"
168
+ task_id = progress.add_task(f"{desc_tpl}: Starting...", total=None)
169
+
170
+ def update_status(msg):
171
+ # update progress description
172
+ progress.update(task_id, description=f"{desc_tpl}: {msg}")
173
+
174
+ stats = runner.run_benchmark(lang, full_path, iterations=args.iter, on_status=update_status)
175
+ progress.remove_task(task_id)
176
+
177
+ if stats:
178
+ results.append({
179
+ 'benchmark': algo,
180
+ 'language': lang,
181
+ **stats
182
+ })
183
+
184
+ print_table(results)
185
+
186
+ if args.json:
187
+ import json
188
+ with open(args.json, 'w') as f:
189
+ json.dump(results, f, indent=2)
190
+ rprint(f"[green]JSON results exported to:[/green] {args.json}")
191
+
192
+ if args.html:
193
+ from .report_generator import generate_html_report
194
+ generate_html_report(results, args.html)
195
+ rprint(f"[green]HTML report generated at:[/green] {args.html}")
196
+
197
+ def interactive_menu():
198
+ rprint(Panel.fit("[bold cyan]Velocicode[/bold cyan]\n[dim]High-Performance Benchmark CLI[/dim]", title="Welcome", border_style="blue"))
199
+ print("1. Run All Benchmarks")
200
+ print("2. Run Specific Algorithm")
201
+ print("3. Run Specific Language")
202
+ print("4. Check Dependencies")
203
+ print("5. Exit")
204
+
205
+ choice = input("Enter choice: ").strip()
206
+
207
+ if choice == '1':
208
+ return ["run"]
209
+ elif choice == '2':
210
+ algos = discover_benchmarks()
211
+ print("\n[bold]Available Algorithms:[/bold]")
212
+ for i, a in enumerate(algos):
213
+ print(f"{i+1}. {a}")
214
+ idx = input("Select algorithm number: ").strip()
215
+ try:
216
+ algo = algos[int(idx)-1]
217
+ return ["run", "--filter-algo", algo]
218
+ except (ValueError, IndexError):
219
+ print("Invalid selection.")
220
+ return interactive_menu()
221
+ elif choice == '3':
222
+ lang = input("Enter language (e.g. python, cpp): ").strip()
223
+ return ["run", "--filter-lang", lang]
224
+ elif choice == '4':
225
+ return ["check"]
226
+ elif choice == '5':
227
+ sys.exit(0)
228
+ else:
229
+ print("Invalid choice.")
230
+ return interactive_menu()
231
+
232
+ if __name__ == "__main__":
233
+ if len(sys.argv) == 1:
234
+ args = interactive_menu()
235
+ # Hack: modify sys.argv so argparse parses our generated args
236
+ sys.argv = [sys.argv[0]] + args
237
+ main()
238
+ else:
239
+ main()
@@ -0,0 +1,143 @@
1
+ import json
2
+ import datetime
3
+
4
+ HTML_TEMPLATE = """
5
+ <!DOCTYPE html>
6
+ <html lang="en">
7
+ <head>
8
+ <meta charset="UTF-8">
9
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
10
+ <title>Velocicode Benchmark Report</title>
11
+ <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
12
+ <style>
13
+ body {{ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; margin: 0; padding: 20px; background: #f4f6f8; }}
14
+ .container {{ max-width: 1000px; margin: 0 auto; background: white; padding: 30px; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.1); }}
15
+ h1 {{ color: #2c3e50; border-bottom: 2px solid #3498db; padding-bottom: 10px; }}
16
+ .meta {{ color: #7f8c8d; font-size: 0.9em; margin-bottom: 30px; }}
17
+ .benchmark-section {{ margin-bottom: 50px; }}
18
+ .chart-container {{ position: relative; height: 300px; width: 100%; }}
19
+ table {{ width: 100%; border-collapse: collapse; margin-top: 20px; }}
20
+ th, td {{ padding: 10px; text-align: left; border-bottom: 1px solid #eee; }}
21
+ th {{ background-color: #f8f9fa; }}
22
+ .rank-1 {{ color: #f1c40f; font-weight: bold; }} /* Gold */
23
+ .rank-2 {{ color: #95a5a6; font-weight: bold; }} /* Silver */
24
+ .rank-3 {{ color: #cd7f32; font-weight: bold; }} /* Bronze */
25
+ </style>
26
+ </head>
27
+ <body>
28
+ <div class="container">
29
+ <h1>Velocicode Report</h1>
30
+ <div class="meta">Generated on: {date}</div>
31
+
32
+ <div id="charts"></div>
33
+ </div>
34
+
35
+ <script>
36
+ const results = {results_json};
37
+
38
+ // Group results by benchmark
39
+ const grouped = {{}};
40
+ results.forEach(r => {{
41
+ if (!grouped[r.benchmark]) grouped[r.benchmark] = [];
42
+ grouped[r.benchmark].push(r);
43
+ }});
44
+
45
+ const container = document.getElementById('charts');
46
+
47
+ // Color palette for languages
48
+ const colors = {{
49
+ 'python': '#3572A5',
50
+ 'cpp': '#f34b7d',
51
+ 'rust': '#dea584',
52
+ 'go': '#00ADD8',
53
+ 'javascript': '#f1e05a'
54
+ }};
55
+
56
+ for (const [benchName, items] of Object.entries(grouped)) {{
57
+ // Sort by mean time
58
+ items.sort((a, b) => a.mean - b.mean);
59
+
60
+ // Create Section
61
+ const section = document.createElement('div');
62
+ section.className = 'benchmark-section';
63
+
64
+ const title = document.createElement('h2');
65
+ title.textContent = `Benchmark: ${{benchName}}`;
66
+ section.appendChild(title);
67
+
68
+ // Canvas for Chart
69
+ const chartDiv = document.createElement('div');
70
+ chartDiv.className = 'chart-container';
71
+ const canvas = document.createElement('canvas');
72
+ chartDiv.appendChild(canvas);
73
+ section.appendChild(chartDiv);
74
+
75
+ // Table
76
+ const table = document.createElement('table');
77
+ table.innerHTML = `
78
+ <thead>
79
+ <tr>
80
+ <th>Rank</th>
81
+ <th>Language</th>
82
+ <th>Time (s)</th>
83
+ <th>Relative Speed</th>
84
+ </tr>
85
+ </thead>
86
+ <tbody>
87
+ ${{items.map((item, index) => {{
88
+ const relative = (item.mean / items[0].mean).toFixed(2) + 'x';
89
+ let rankClass = '';
90
+ let rankIcon = index + 1;
91
+ if (index === 0) {{ rankIcon = '🥇'; rankClass='rank-1'; }}
92
+ if (index === 1) {{ rankIcon = '🥈'; rankClass='rank-2'; }}
93
+ if (index === 2) {{ rankIcon = '🥉'; rankClass='rank-3'; }}
94
+
95
+ return `<tr>
96
+ <td class="${{rankClass}}">${{rankIcon}}</td>
97
+ <td>${{item.language}}</td>
98
+ <td>${{item.mean.toFixed(4)}}</td>
99
+ <td>${{relative}}</td>
100
+ </tr>`;
101
+ }}).join('')}}
102
+ </tbody>
103
+ `;
104
+ section.appendChild(table);
105
+
106
+ container.appendChild(section);
107
+
108
+ // Render Chart
109
+ new Chart(canvas, {{
110
+ type: 'bar',
111
+ data: {{
112
+ labels: items.map(i => i.language),
113
+ datasets: [{{
114
+ label: 'Execution Time (seconds) - Lower is Better',
115
+ data: items.map(i => i.mean),
116
+ backgroundColor: items.map(i => colors[i.language] || '#cccccc'),
117
+ borderColor: '#222',
118
+ borderWidth: 1
119
+ }}]
120
+ }},
121
+ options: {{
122
+ responsive: true,
123
+ maintainAspectRatio: false,
124
+ indexAxis: 'y',
125
+ scales: {{
126
+ x: {{ beginAtZero: true, title: {{ display: true, text: 'Seconds' }} }}
127
+ }}
128
+ }}
129
+ }});
130
+ }}
131
+ </script>
132
+ </body>
133
+ </html>
134
+ """
135
+
136
+ def generate_html_report(results, output_path):
137
+ report_html = HTML_TEMPLATE.format(
138
+ date=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
139
+ results_json=json.dumps(results)
140
+ )
141
+
142
+ with open(output_path, 'w') as f:
143
+ f.write(report_html)
velocicode/reporter.py ADDED
@@ -0,0 +1,79 @@
1
+ from rich import print
2
+ from rich.table import Table
3
+ from rich.console import Console
4
+
5
+ def print_table(results):
6
+ if not results:
7
+ print("[yellow]No results to display[/yellow]")
8
+ return
9
+
10
+ console = Console()
11
+
12
+ # 1. Group by Benchmark
13
+ grouped = {}
14
+ for r in results:
15
+ bench_name = r['benchmark']
16
+ if bench_name not in grouped:
17
+ grouped[bench_name] = []
18
+ grouped[bench_name].append(r)
19
+
20
+ # 2. Process each group
21
+ for bench_name, group_results in grouped.items():
22
+ # Sort by mean time (fastest first)
23
+ group_results.sort(key=lambda x: x['mean'])
24
+
25
+ # Determine baseline (fastest)
26
+ if not group_results:
27
+ continue
28
+
29
+ fastest_time = group_results[0]['mean']
30
+
31
+ # Create Table
32
+ table = Table(
33
+ title=f"Benchmark: [bold cyan]{bench_name}[/bold cyan]",
34
+ show_header=True,
35
+ header_style="bold white",
36
+ border_style="blue",
37
+ expand=True
38
+ )
39
+
40
+ table.add_column("Rank", style="bold yellow", justify="center", width=4)
41
+ table.add_column("Language", style="magenta", width=12)
42
+ table.add_column("Time (s)", justify="right")
43
+ table.add_column("Relative", justify="right")
44
+ table.add_column("Min (s)", style="dim", justify="right")
45
+ table.add_column("Max (s)", style="dim", justify="right")
46
+
47
+ for i, r in enumerate(group_results):
48
+ # Rank
49
+ rank_display = str(i + 1)
50
+ if i == 0:
51
+ rank_display = "🥇"
52
+ elif i == 1:
53
+ rank_display = "🥈"
54
+ elif i == 2:
55
+ rank_display = "🥉"
56
+
57
+ # Relative Speed
58
+ rel_speed = r['mean'] / fastest_time
59
+ rel_str = f"{rel_speed:.2f}x"
60
+
61
+ # Colorize Relative Speed
62
+ if rel_speed < 1.05:
63
+ rel_style = "[green]"
64
+ elif rel_speed < 5.0:
65
+ rel_style = "[yellow]"
66
+ else:
67
+ rel_style = "[red]"
68
+
69
+ table.add_row(
70
+ rank_display,
71
+ r['language'],
72
+ f"{r['mean']:.4f}",
73
+ f"{rel_style}{rel_str}[/]",
74
+ f"{r['min']:.4f}",
75
+ f"{r['max']:.4f}"
76
+ )
77
+
78
+ console.print(table)
79
+ console.print("") # Newline between tables
velocicode/runner.py ADDED
@@ -0,0 +1,65 @@
1
+ import subprocess
2
+ import time
3
+ import os
4
+ import shutil
5
+
6
+ class BenchmarkRunner:
7
+ def __init__(self, config):
8
+ self.config = config
9
+
10
+
11
+
12
+ def run_benchmark(self, language, source_path, iterations=5, on_status=None):
13
+ def log(msg):
14
+ if on_status:
15
+ on_status(msg)
16
+ else:
17
+ print(msg)
18
+
19
+ lang_config = self.config.get('languages', {}).get(language)
20
+ if not lang_config:
21
+ raise ValueError(f"Unknown language: {language}")
22
+
23
+ # Prepare output binary path if needed
24
+ bin_dir = os.path.join(os.path.dirname(source_path), 'bin')
25
+ os.makedirs(bin_dir, exist_ok=True)
26
+ bin_name = f"runner_{language}"
27
+ bin_path = os.path.join(bin_dir, bin_name)
28
+
29
+ # Compile if necessary
30
+ try:
31
+ compile_cmd_tpl = lang_config.get('compile')
32
+ if compile_cmd_tpl:
33
+ cmd = compile_cmd_tpl.format(source=source_path, out=bin_path)
34
+ log(f"Compiling...")
35
+ subprocess.check_call(cmd, shell=True)
36
+ else:
37
+ # No compilation needed
38
+ pass
39
+ except subprocess.CalledProcessError as e:
40
+ log(f"[red]Compilation failed[/red]: {e}")
41
+ return None
42
+
43
+ run_cmd_tpl = lang_config.get('run')
44
+ # If compiled, use bin_path, else use source_path
45
+ cmd = run_cmd_tpl.format(source=source_path, out=bin_path)
46
+
47
+ times = []
48
+ for i in range(iterations):
49
+ log(f"Running iteration {i+1}/{iterations}...")
50
+ start = time.time()
51
+ try:
52
+ subprocess.check_call(cmd, shell=True, stdout=subprocess.DEVNULL)
53
+ duration = time.time() - start
54
+ times.append(duration)
55
+ except subprocess.CalledProcessError as e:
56
+ log(f"[red]Runtime error[/red]: {e}")
57
+ return None
58
+
59
+ # simple stats
60
+ return {
61
+ 'mean': sum(times) / len(times),
62
+ 'min': min(times),
63
+ 'max': max(times),
64
+ 'count': len(times)
65
+ }
@@ -0,0 +1,23 @@
1
+ import platform
2
+ import psutil
3
+ import cpuinfo
4
+
5
+ def get_system_info():
6
+ """
7
+ Returns a dictionary containing system information.
8
+ """
9
+ cpu_info = cpuinfo.get_cpu_info()
10
+ cpu_model = cpu_info.get('brand_raw', 'Unknown CPU')
11
+ arch = platform.machine()
12
+
13
+ ram_bytes = psutil.virtual_memory().total
14
+ ram_gb = ram_bytes / (1024**3)
15
+
16
+ os_info = f"{platform.system()} {platform.release()}"
17
+
18
+ return {
19
+ "os": os_info,
20
+ "cpu": cpu_model,
21
+ "arch": arch,
22
+ "ram": f"{ram_gb:.1f} GB"
23
+ }
@@ -0,0 +1,92 @@
1
+ Metadata-Version: 2.4
2
+ Name: Velocicode
3
+ Version: 0.5.0
4
+ Summary: A CLI tool for programming language speed benchmarks
5
+ Author-email: Code Agent <agent@example.com>
6
+ Classifier: Programming Language :: Python :: 3
7
+ Classifier: License :: OSI Approved :: MIT License
8
+ Classifier: Operating System :: OS Independent
9
+ Requires-Python: >=3.7
10
+ Description-Content-Type: text/markdown
11
+ License-File: LICENSE
12
+ Requires-Dist: pyyaml
13
+ Requires-Dist: rich>=13.0.0
14
+ Requires-Dist: psutil
15
+ Requires-Dist: py-cpuinfo
16
+ Dynamic: license-file
17
+
18
+ # Velocicode 🚀
19
+
20
+ **Velocicode** is a high-performance command-line tool for benchmarking programming language speeds. It allows you to run standard algorithms across multiple languages and compare their execution time with professional, interactive reports.
21
+
22
+ ## Features ✨
23
+
24
+ - **Multi-Language Support**: Benchmarks **Python**, **C++**, **Rust**, **Go**, and **JavaScript** (Node.js).
25
+ - **Smart Execution**:
26
+ - **System Info**: Auto-detects your CPU, RAM, and OS.
27
+ - **Dependency Check**: Automatically checks for compilers and skips missing languages.
28
+ - **Premium UI**:
29
+ - Beautiful terminal output using the **Rich** library.
30
+ - Rankings with Medals (🥇 🥈 🥉).
31
+ - Relative Speed comparisons (e.g., `1.00x` vs `45.9x`).
32
+ - **Data Export**:
33
+ - **JSON**: Raw data export for analysis.
34
+ - **HTML**: Interactive reports with **Charts** for presentations.
35
+
36
+ ## Installation
37
+
38
+ ```bash
39
+ pip install velocicode
40
+ ```
41
+
42
+ ## Usage
43
+
44
+ ### 1. Run Benchmarks
45
+
46
+ Run all benchmarks with default settings:
47
+
48
+ ```bash
49
+ velocicode run
50
+ ```
51
+
52
+ The tool will display your system information and check if you have the necessary compilers. If some are missing, it will ask if you want to proceed with the available ones.
53
+
54
+ Filter by specific algorithm or language:
55
+
56
+ ```bash
57
+ # Run only Matrix Multiplication in Rust and Go
58
+ velocicode run --filter-algo matrix_mul --filter-lang rust,go
59
+ ```
60
+
61
+ ### 2. Generate Reports 📊
62
+
63
+ Export results to JSON or generate a visual HTML report:
64
+
65
+ ```bash
66
+ velocicode run --html report.html --json results.json
67
+ ```
68
+
69
+ Open `report.html` in your browser to see interactive bar charts!
70
+
71
+ ### 3. Check Compilers
72
+
73
+ Velocicode relies on system compilers. Check what you have installed:
74
+
75
+ ```bash
76
+ velocicode check
77
+ ```
78
+
79
+ ## Requirements
80
+
81
+ > [!IMPORTANT]
82
+ > This tool requires external compilers. `pip` installs the runner, but you need the languages installed:
83
+
84
+ - **Python 3.7+**
85
+ - `g++` (for C++)
86
+ - `rustc` (for Rust)
87
+ - `go` (for Go)
88
+ - `node` (for JavaScript)
89
+
90
+ ## License
91
+
92
+ MIT
@@ -0,0 +1,33 @@
1
+ velocicode/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ velocicode/config.yaml,sha256=-9AMoCq1SsHgbBzDk0DZhnwxGev_hFM1mq_az-teJnw,325
3
+ velocicode/main.py,sha256=YSTF4zhguej2QZg8a-miK0UgLV9Sik2VUCnC57WycCE,8437
4
+ velocicode/report_generator.py,sha256=hXaO6Vf6AxVep4SYlJifeoAYRnWwCjfjSluOb1NxOQQ,5507
5
+ velocicode/reporter.py,sha256=o7byb2SpSF1o6kbr9yhWdLPV3-wem8L6_gY-0DoTz8o,2484
6
+ velocicode/runner.py,sha256=8sUhLJhTCL5wWGZ6IJcaDn4MHdUugxUTINds2LKdFXM,2104
7
+ velocicode/system_info.py,sha256=pUHUr6aRnGeXAprcYgCpLntzhpbLRpU50DXvfWz5Fu4,544
8
+ velocicode/benchmarks/fibonacci/cpp/main.cpp,sha256=fU0cJUofLBHXM6i_d4LA-f8xZoGyLBQvCTFS2mqHrXA,285
9
+ velocicode/benchmarks/fibonacci/go/main.go,sha256=a94v7GVuqpVkGrjFFU6xRXZ4B4zJ-IAbYIG0CRM2pvI,274
10
+ velocicode/benchmarks/fibonacci/javascript/main.js,sha256=A-rTit4G6USJ2FWaxTBC18O41AdCn84kWv9S0R5JIVE,193
11
+ velocicode/benchmarks/fibonacci/python/main.py,sha256=gYD1pC5jKckc1GvqoDpppToPssKn0w7v73LsLo5okF8,203
12
+ velocicode/benchmarks/fibonacci/rust/main.rs,sha256=tXIltVAP4M6mEVGTe5IkFTmWHwZiGReTGpnwwf3PiUY,304
13
+ velocicode/benchmarks/matrix_mul/cpp/main.cpp,sha256=H1wLUuMfsLP1l9qH4igXWFiRnDTfBMck8WHv5TcfTIM,1004
14
+ velocicode/benchmarks/matrix_mul/go/main.go,sha256=_dN1D650fZp7dp0utdpqbwO8UXebmwNnTmDIN76wKR0,737
15
+ velocicode/benchmarks/matrix_mul/javascript/main.js,sha256=_trWvLtlwzme6bLudDkWljPb9teo8GRikv1m7OqWh6k,693
16
+ velocicode/benchmarks/matrix_mul/python/main.py,sha256=j2c9tJaOA5Zn4aB9cPAQvtlOuQOfgHcPyGWAXK9fpPg,590
17
+ velocicode/benchmarks/matrix_mul/rust/main.rs,sha256=IT15ptLggEP_3q_iZ1RBIAs3pPPteZ6ZAvnkogELPOw,827
18
+ velocicode/benchmarks/primes/cpp/main.cpp,sha256=dtBbXZ_Z_grhVV3rW0TX_gYreWW5kaeMB1AFZt2gm-U,558
19
+ velocicode/benchmarks/primes/go/main.go,sha256=PxZFltOWXxqK7XpBPC7tRfLsr502j0-ORlYvj8ZZhNI,519
20
+ velocicode/benchmarks/primes/javascript/main.js,sha256=6ok5TFHOX-P_yemnBTjTDMeHr7BqqsTB9uh92-kNfaA,465
21
+ velocicode/benchmarks/primes/python/main.py,sha256=jhlKq2KDMYnjmVt1eFzgodFFF3EPv1hlGjmHOqHt1x4,470
22
+ velocicode/benchmarks/primes/rust/main.rs,sha256=-fuEJFULB9MHpxGmdc1HlD7lTL9ZOpbEj0HWiRrjWDA,643
23
+ velocicode/benchmarks/quicksort/cpp/main.cpp,sha256=2s1l6zrBJuUjiY_BZnFcN01ow9l4GcyGZzmRwJcSOhE,462
24
+ velocicode/benchmarks/quicksort/go/main.go,sha256=9I8Onqf_tzqoRqDeP-RTp2t47ofYkYbR277-ABF_ias,323
25
+ velocicode/benchmarks/quicksort/javascript/main.js,sha256=wUSfEIb4QIk-r1u5P1aaoKu9n7Rd8FpI1mDpgE1N3WE,246
26
+ velocicode/benchmarks/quicksort/python/main.py,sha256=UBpRHGJ3r32UAYmpwa_8cN8urI1O-VH1Xza-OduP-y0,652
27
+ velocicode/benchmarks/quicksort/rust/main.rs,sha256=30uWtnz8ZkHcfiqMKln_nTHmQcytJ-XtY-TOk0kzZKo,918
28
+ velocicode-0.5.0.dist-info/licenses/LICENSE,sha256=ESYyLizI0WWtxMeS7rGVcX3ivMezm-HOd5WdeOh-9oU,1056
29
+ velocicode-0.5.0.dist-info/METADATA,sha256=Ug1b2roBf3KSWpMN8j-7UDWCvHZ_M3KBAG1vwbeDdnE,2482
30
+ velocicode-0.5.0.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
31
+ velocicode-0.5.0.dist-info/entry_points.txt,sha256=OhCJJRwEh3bhmwUpd1oML4Ta-KLX3a9dq7Mu7mNi-pc,52
32
+ velocicode-0.5.0.dist-info/top_level.txt,sha256=zphesZGvGtNa8jw8Bpmx9byQPHk-YnNEWuK7s_hdX0E,11
33
+ velocicode-0.5.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.10.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ velocicode = velocicode.main:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ velocicode