From a8abf7f0b03b7d4f0532119f679466182e6d60b8 Mon Sep 17 00:00:00 2001 From: ernesto Date: Mon, 30 Jun 2025 22:47:55 -0300 Subject: [PATCH 1/5] Copy uncommitted changes Applied uncommitted changes from local repository --- CLAUDE.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..cb9840d --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,5 @@ +ALWAYS use ONLY Environments for ANY and ALL file, code, or shell operations—NO EXCEPTIONS—even for simple or generic requests. + +DO NOT install or use the git cli with the environment_run_cmd tool. All environment tools will handle git operations for you. Changing ".git" yourself will compromise the integrity of your environment. + +You MUST inform the user how to view your work using `cu log ` AND `cu checkout `. Failure to do this will make your work inaccessible to others. From 42f1ef1ebc6d5dd058fba059c8dbf5e3836b2647 Mon Sep 17 00:00:00 2001 From: ernesto Date: Mon, 30 Jun 2025 22:48:30 -0300 Subject: [PATCH 2/5] Create env healthy-aardvark Creating environment to update README file using container-use MCP. --- .container-use/AGENT.md | 1 + .container-use/environment.json | 4 ++++ 2 files changed, 5 insertions(+) create mode 100644 .container-use/AGENT.md create mode 100644 .container-use/environment.json diff --git a/.container-use/AGENT.md b/.container-use/AGENT.md new file mode 100644 index 0000000..77916d1 --- /dev/null +++ b/.container-use/AGENT.md @@ -0,0 +1 @@ +No instructions found. Please look around the filesystem and update me \ No newline at end of file diff --git a/.container-use/environment.json b/.container-use/environment.json new file mode 100644 index 0000000..b177302 --- /dev/null +++ b/.container-use/environment.json @@ -0,0 +1,4 @@ +{ + "workdir": "/workdir", + "base_image": "ubuntu:24.04" +} \ No newline at end of file From 913c96ba07f7055095ec499b3464f12e55b01e61 Mon Sep 17 00:00:00 2001 From: ernesto Date: Mon, 30 Jun 2025 22:50:53 -0300 Subject: [PATCH 3/5] Write README.md Writing comprehensive README with project overview and structure. --- README.md | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c4a9bbf..1086ff5 100644 --- a/README.md +++ b/README.md @@ -1 +1,60 @@ -# code-challenges \ No newline at end of file +# Code Challenges + +This repository contains a collection of coding challenges and implementations, covering various programming concepts, tools, and system designs. + +## Projects + +### System Tools & Utilities +- **cat** - File concatenation utility +- **cut** - Text column extraction tool +- **grep** - Pattern searching utility +- **head** - File header display tool +- **sed** - Stream editor implementation +- **tar** - Archive manipulation tool +- **uniq** - Duplicate line removal utility +- **wc** - Word, line, and character counting tool + +### Network & System Services +- **forward-proxy** - HTTP proxy server implementation +- **memcache-server** - In-memory caching server +- **monitoring-service** - URL monitoring and alerting system +- **port-scanner** - Network port scanning utility +- **rate-limiter** - Request rate limiting service +- **redis-cli** - Redis client implementation + +### Development Tools +- **file-finder** - File search and discovery tool +- **git-contribution** - Git contribution graph generator +- **shell** - Command shell implementation +- **static-site-generator** - Static website generator +- **zipcracker** - ZIP file password cracking utility + +### Specialized Applications +- **cron-decoder** - Cron expression parser and decoder +- **password-manager** - Secure password management system + +## Languages & Technologies + +Projects in this repository are implemented using various programming languages including: +- Go +- Python +- JavaScript/Node.js +- Shell scripting + +## Getting Started + +Each project directory contains its own implementation with relevant source files, dependencies, and documentation. Navigate to individual project directories to explore specific implementations. + +## Structure + +``` +├── project-name/ +│ ├── source files +│ ├── dependencies (go.mod, package.json, etc.) +│ └── project-specific files +└── README.md +``` + +## Contributing + +This repository serves as a collection of coding challenges and learning exercises. Each project demonstrates different programming concepts, algorithms, and system design patterns. \ No newline at end of file From 30d17a469caf9cba240b73b35b5409ea864d3381 Mon Sep 17 00:00:00 2001 From: ernesto Date: Mon, 30 Jun 2025 23:18:28 -0300 Subject: [PATCH 4/5] Write LICENSE Creating MIT license file for the repository --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3e4c433 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file From 71587da7c9c17d54a5d935e49b27731ead83e983 Mon Sep 17 00:00:00 2001 From: ernesto Date: Tue, 19 Aug 2025 02:25:31 -0300 Subject: [PATCH 5/5] feat: add initial implementation for CPU usage monitoring --- top/go.mod | 7 +++ top/go.sum | 4 ++ top/main.go | 149 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 160 insertions(+) create mode 100644 top/go.mod create mode 100644 top/go.sum create mode 100644 top/main.go diff --git a/top/go.mod b/top/go.mod new file mode 100644 index 0000000..9c91ec3 --- /dev/null +++ b/top/go.mod @@ -0,0 +1,7 @@ +module top + +go 1.24.0 + +require golang.org/x/term v0.34.0 + +require golang.org/x/sys v0.35.0 // indirect diff --git a/top/go.sum b/top/go.sum new file mode 100644 index 0000000..3f53607 --- /dev/null +++ b/top/go.sum @@ -0,0 +1,4 @@ +golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= +golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4= +golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw= diff --git a/top/main.go b/top/main.go new file mode 100644 index 0000000..ff501f8 --- /dev/null +++ b/top/main.go @@ -0,0 +1,149 @@ +package main + +import ( + "bufio" + "fmt" + "os" + "strconv" + "strings" + "time" + + "golang.org/x/term" +) + +type CPUStats struct { + user, nice, system, idle, iowait, irq, softirq, steal uint64 +} + +var prevCPUStats *CPUStats + +func main() { + // Get the file descriptor for standard input + fd := int(os.Stdin.Fd()) + + // Check if standard input is a terminal + if !term.IsTerminal(fd) { + fmt.Println("Not running in a terminal.") + return + } + + // Save the original terminal state so we can restore it later + oldState, err := term.GetState(fd) + if err != nil { + panic(err) + } + defer term.Restore(fd, oldState) + + // Put the terminal into raw mode. This disables input echoing. + _, err = term.MakeRaw(fd) + if err != nil { + panic(err) + } + + // Take two quick readings to calculate initial CPU usage + prevCPUStats, _ = readCPUStats() + time.Sleep(100 * time.Millisecond) // Very brief pause + printSystemInfo() + + // Create a ticker for 5-second intervals + ticker := time.NewTicker(5 * time.Second) + defer ticker.Stop() + + // Channel for keyboard input + inputCh := make(chan byte, 1) + + // Goroutine to handle keyboard input + go func() { + for { + var buf [1]byte + _, err := os.Stdin.Read(buf[:]) + if err != nil { + return + } + inputCh <- buf[0] + } + }() + + // Main event loop + for { + select { + case <-ticker.C: + printSystemInfo() + + case char := <-inputCh: + // Handle keyboard input + if char == 'q' || char == 'Q' || char == 3 { // 'q', 'Q', or Ctrl+C + fmt.Println() + return + } + } + } +} + +func readCPUStats() (*CPUStats, error) { + file, err := os.Open("/proc/stat") + if err != nil { + return nil, err + } + defer file.Close() + + scanner := bufio.NewScanner(file) + if !scanner.Scan() { + return nil, fmt.Errorf("failed to read CPU line") + } + + line := scanner.Text() + fields := strings.Fields(line) + if len(fields) < 8 || fields[0] != "cpu" { + return nil, fmt.Errorf("invalid CPU line format") + } + + stats := &CPUStats{} + values := []*uint64{&stats.user, &stats.nice, &stats.system, &stats.idle, + &stats.iowait, &stats.irq, &stats.softirq, &stats.steal} + + for i, val := range values { + parsed, err := strconv.ParseUint(fields[i+1], 10, 64) + if err != nil { + return nil, err + } + *val = parsed + } + + return stats, nil +} + +func calculateCPUUsage(prev, curr *CPUStats) float64 { + if prev == nil { + return 0.0 + } + + prevTotal := prev.user + prev.nice + prev.system + prev.idle + prev.iowait + prev.irq + prev.softirq + prev.steal + currTotal := curr.user + curr.nice + curr.system + curr.idle + curr.iowait + curr.irq + curr.softirq + curr.steal + + totalDiff := currTotal - prevTotal + idleDiff := curr.idle - prev.idle + + if totalDiff == 0 { + return 0.0 + } + + return (1.0 - float64(idleDiff)/float64(totalDiff)) * 100.0 +} + +func printSystemInfo() { + currentTime := time.Now() + cpuStats, err := readCPUStats() + + var cpuUsage float64 + if err == nil { + cpuUsage = calculateCPUUsage(prevCPUStats, cpuStats) + prevCPUStats = cpuStats + } + + if err != nil { + fmt.Printf("\rTime: %s | CPU: --%%", currentTime.Format("15:04:05")) + } else { + fmt.Printf("\rTime: %s | CPU: %.1f%%", currentTime.Format("15:04:05"), cpuUsage) + } +}