Wednesday, September 30, 2026

TextBox handling using Python

 I converted a simple text box input taking method to some modern python implementation

/* program to implement text box press esc key to terminate with comments

*/

#include <graphics.h>

int poly[8];         // a polygon to display the textbox

int curposx=100,curposy=100;   // current cursor position

int flag;                      // flag to indicate blinking of cursor

char str[20];                  // string containing typed text

// Function to draw cursor while blinking it

void drawcursor()

{

     if(flag==0)

     setcolor(WHITE);

     else setcolor(BLACK);

     line(curposx,curposy,curposx,curposy+20);

}

// Function to display key(character) typed

void display(char key[2])

{

  int len;

  cleardevice();

  setfillstyle(1,LIGHTGRAY);

  setcolor(WHITE);

  fillpoly(4,poly);

  flag=(flag==0)?1:0;

  switch(key[0])

  {

           case 8:          // if backspace is pressed delete the last character from str

                len=strlen(str);

                if(strlen!=0)

                {

           str[len-1]='\0';   

           curposx-=7;     

           }

           break;

           case '\0':      // if the key string is empty then do nothing

                break;

           default:

                   strcat(str,key);

                   curposx+=7;

  }


      outtextxy(100,106,str);

      drawcursor();

   }

  int main( )

  {

  char key[2];

  int keycount=0,enough=0,len;

    /* our polygon array */


   poly[0]=100;poly[1]=100;poly[2]=200;poly[3]=100;

   poly[4]=200;poly[5]=130;poly[6]=100;poly[7]=130;

   

    initwindow(400, 300, "Form");

    key[0]='\0';

    flag=0;// set the flag for cursor blinking

    if(kbhit())        key[0]=getch();// get the character typed if any before the loop starts

    key[1]='\0';

        while(key[0]!=27)        // if it is not escape be in loop

        {

          key[0]='\0';            // destroy the key code from previous loop run

        delay(200);           //delay for cursor blinking

        if(kbhit()) {         // if keyboard is hit

                    key[0]=getch();    //get the key code of pressed key

                    keycount++;     // increment the key count

               if(keycount>18)      // If key count greater than 18 stop taking input

               enough=1;

                    }

                    if(enough) key[0]='\0';  //if enough set key code to zero

        display(key);

}

    // set the last character as "\0" to terminate the str

    len=strlen(str);

    if(len>0)

    {

    str[len-1]='\0';

    }

    setcolor(WHITE);

    outtextxy(200,200,str);

    printf("%d,%s",len,str);

    getch();

    return 0;

}






Updated code:

"""
A small, reusable text box widget for pygame 2.

    pip install pygame
    python textbox.py

Click the box to focus it. Enter submits, Esc quits.
Supports: insertion at the cursor, Backspace/Delete, Left/Right/Home/End,
click-to-position, key repeat, max length, placeholder and horizontal scrolling.
"""
import pygame

BG = (30, 30, 36)
BOX_IDLE = (70, 70, 80)
BOX_ACTIVE = (90, 160, 255)
TEXT = (235, 235, 240)
HINT = (120, 120, 130)

BLINK_MS = 500  # cursor is visible for 500 ms, hidden for 500 ms


class TextBox:
    PAD = 8

    def __init__(self, rect, font, max_length=20, placeholder=""):
        self.rect = pygame.Rect(rect)
        self.font = font
        self.max_length = max_length
        self.placeholder = placeholder
        self.text = ""
        self.cursor = 0          # index in self.text where the caret sits
        self.active = False
        self._scroll = 0         # horizontal pixel offset of the text
        self._blink_start = pygame.time.get_ticks()

    # ---------- helpers ----------
    def _touch(self):
        """Restart the blink cycle so the caret is visible right after input."""
        self._blink_start = pygame.time.get_ticks()

    def _caret_x(self):
        return self.font.size(self.text[: self.cursor])[0]

    def _update_scroll(self):
        """Keep the caret inside the visible area."""
        visible = self.rect.width - 2 * self.PAD
        caret = self._caret_x()
        if caret - self._scroll > visible:
            self._scroll = caret - visible
        elif caret - self._scroll < 0:
            self._scroll = caret
        self._scroll = max(0, self._scroll)

    def _index_at(self, mouse_x):
        """Character index nearest to a mouse x position."""
        x = mouse_x - self.rect.x - self.PAD + self._scroll
        best, best_dist = 0, float("inf")
        for i in range(len(self.text) + 1):
            dist = abs(self.font.size(self.text[:i])[0] - x)
            if dist < best_dist:
                best, best_dist = i, dist
        return best

    # ---------- events ----------
    def handle_event(self, event):
        """Feed every pygame event here. Returns the text when Enter is pressed."""
        if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
            self.active = self.rect.collidepoint(event.pos)
            if self.active:
                self.cursor = self._index_at(event.pos[0])
                self._touch()
            return None

        if not self.active:
            return None

        if event.type == pygame.TEXTINPUT:
            # TEXTINPUT already handles shift, layouts and IMEs correctly.
            chunk = "".join(c for c in event.text if c.isprintable())
            chunk = chunk[: self.max_length - len(self.text)]
            if chunk:
                self.text = self.text[: self.cursor] + chunk + self.text[self.cursor:]
                self.cursor += len(chunk)

        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_BACKSPACE and self.cursor > 0:
                self.text = self.text[: self.cursor - 1] + self.text[self.cursor:]
                self.cursor -= 1
            elif event.key == pygame.K_DELETE:
                self.text = self.text[: self.cursor] + self.text[self.cursor + 1:]
            elif event.key == pygame.K_LEFT:
                self.cursor = max(0, self.cursor - 1)
            elif event.key == pygame.K_RIGHT:
                self.cursor = min(len(self.text), self.cursor + 1)
            elif event.key == pygame.K_HOME:
                self.cursor = 0
            elif event.key == pygame.K_END:
                self.cursor = len(self.text)
            elif event.key in (pygame.K_RETURN, pygame.K_KP_ENTER):
                return self.text
            else:
                return None
        else:
            return None

        self._touch()
        return None

    # ---------- drawing ----------
    def draw(self, surface):
        pygame.draw.rect(surface, (45, 45, 54), self.rect, border_radius=6)
        pygame.draw.rect(surface, BOX_ACTIVE if self.active else BOX_IDLE,
                         self.rect, width=2, border_radius=6)

        self._update_scroll()
        inner = self.rect.inflate(-2 * self.PAD, -4)
        old_clip = surface.get_clip()
        surface.set_clip(inner)

        if self.text:
            img = self.font.render(self.text, True, TEXT)
        else:
            img = self.font.render(self.placeholder, True, HINT)
        y = self.rect.centery - img.get_height() // 2
        surface.blit(img, (inner.x - self._scroll, y))

        # Blink using elapsed time, so the main loop never has to sleep.
        blink_on = ((pygame.time.get_ticks() - self._blink_start) // BLINK_MS) % 2 == 0
        if self.active and blink_on:
            cx = inner.x - self._scroll + self._caret_x()
            pygame.draw.line(surface, TEXT, (cx, y), (cx, y + img.get_height()), 2)

        surface.set_clip(old_clip)


def main():
    pygame.init()
    screen = pygame.display.set_mode((480, 240))
    pygame.display.set_caption("Text box")
    font = pygame.font.SysFont("segoeui,arial", 24)
    clock = pygame.time.Clock()

    box = TextBox((40, 80, 400, 44), font, max_length=20, placeholder="Type here...")
    box.active = True
    pygame.key.set_repeat(400, 35)   # hold a key to repeat it
    pygame.key.start_text_input()

    submitted = ""
    running = True
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT or (
                event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE
            ):
                running = False
            result = box.handle_event(event)
            if result is not None:
                submitted = result

        screen.fill(BG)
        box.draw(screen)
        if submitted:
            msg = font.render(f"Submitted: {submitted!r} ({len(submitted)} chars)", True, HINT)
            screen.blit(msg, (40, 160))
        pygame.display.flip()
        clock.tick(60)

    pygame.quit()


if __name__ == "__main__":
    main()

Thursday, September 3, 2026

Sankey chart of user abilities

 Prompt: If there is a software development model where the features on a per user basis are enabled or disabled using remote config by orchestrating the parameters.. will we be able to generate a sankey chart that depicts users adept at a particular feature

Yes — absolutely, and it could actually be a very useful visualization for the kind of software-development model you're describing.

The key is to distinguish configuration from actual usage.

Your model

Imagine your application has:

  • Users: U1, U2, U3, ...

  • Features: F1, F2, F3, ...

  • Remote configuration determining whether a feature is enabled

  • Parameters controlling how a feature behaves

For example:

UserFeature AFeature BFeature C
U1EnabledEnabledDisabled
U2EnabledDisabledEnabled
U3DisabledEnabledEnabled

You could then collect runtime telemetry such as:

User → Configuration → Feature → Action/Usage

and construct a Sankey such as:

                    ┌── Feature A ── Used
                    │
Users ──→ Config ───┼── Feature B ── Used
                    │
                    └── Feature C ── Not Used

But there's a more interesting version.

You can make the Sankey represent the user's "feature journey"

For example:

                 ┌── Search ────────┐
                 │                   ↓
Users ──→ Enabled Features ──→ Used Features ──→ Successful Outcome
                 │                   ↑
                 ├── Recommendations ┘
                 │
                 └── Analytics

The width of each flow represents the number of users.

So you might discover:

10,000 Users
   │
   ├── 8,000 → Feature A enabled
   │              └── 6,200 actually used
   │
   ├── 6,500 → Feature B enabled
   │              └── 1,100 actually used
   │
   └── 4,000 → Feature C enabled
                  └── 3,800 actually used

That immediately tells you something that a conventional feature-usage bar chart doesn't: where users are being enabled, filtered, and subsequently flowing through the system.

The really interesting research/software-engineering angle

If your remote configuration is parameterized, you can add another dimension:

User → Configuration → Feature → Parameter → Behaviour → Outcome

For example:

                     ┌─ Search ── threshold=0.7 ── Success
                     │
Users → Remote Config┼─ Search ── threshold=0.9 ── Abandoned
                     │
                     └─ Recommendations ────────── Success

Now the Sankey isn't merely saying "who uses Feature X?"

It can answer:

"How do different configuration decisions cause different populations of users to flow through different features and ultimately produce different outcomes?"

That's much more powerful.

One important caveat

A Sankey doesn't by itself tell you that users are "adept" at a feature.

It tells you about flows and quantities.

If by adept you mean something like:

  • users who successfully completed the feature,

  • users who use it repeatedly,

  • users with high proficiency,

  • users who require fewer attempts,

  • users who achieve a desired outcome,

then you need to define an adeptness metric first.

For example:

Adept user =
    Feature enabled
    AND used ≥ 5 times
    AND success rate ≥ 80%

Then your flow could become:

All Users
    ↓
Feature Enabled
    ↓
Feature Used
    ↓
Repeated Usage
    ↓
Successful Usage
    ↓
Adept Users

That is a very natural Sankey representation.

If you're thinking of this as a software architecture / research model, there's an even more interesting possibility: treating the remote configuration system as a feature orchestration layer, and the Sankey as a runtime observability model of user-feature affinity. That could be developed into a fairly concrete framework rather than just a visualization.

Prompt: Can I solicit user abilities from other websites to research on gaps in them? like competencies and suggest users some new features to try

Yes — technically and conceptually, this is possible, but there is an important distinction between soliciting abilities and silently collecting them.

What you're describing could become a very interesting extension of your remote-configuration idea:

Build a user competency profile from consented signals available across services, identify gaps, and use those gaps to recommend features or learning opportunities.

A possible architecture

External Sources
     │
     ├── GitHub ───────┐
     ├── LinkedIn ─────┤
     ├── Stack Overflow┤
     ├── Learning sites ┤
     └── Your application
                      │
                      ▼
             ┌─────────────────┐
             │ Competency      │
             │ Extraction      │
             │                 │
             │ JavaScript  4/5 │
             │ React      3/5 │
             │ Git        5/5 │
             │ GraphQL    1/5 │
             └────────┬────────┘
                      │
                      ▼
              Competency Graph
                      │
             ┌────────┴────────┐
             ▼                 ▼
       Strengths             Gaps
                              │
                              ▼
                    Feature Recommendations
                              │
                              ▼
                    Remote Configuration
                              │
                              ▼
                         User tries
                              │
                              ▼
                         Telemetry
                              │
                              ▼
                    Updated competency

The interesting part is that the recommendation itself becomes an experiment.

Suppose your system detects:

User competency

React        █████  5
JavaScript   ████   4
REST APIs    ███    3
GraphQL      █      1

Your application might decide:

"This user has strong React and REST experience but relatively little GraphQL exposure."

It could remotely enable a GraphQL exploration feature for that user.

Then you measure:

Recommended
     ↓
Feature enabled
     ↓
Feature opened
     ↓
Feature attempted
     ↓
Feature successfully completed
     ↓
Repeated usage

Now your Sankey idea becomes particularly powerful.

You could connect competency → recommendation → adoption

For example:

Users
 │
 ├──────────────→ Strong React
 │
 ├──────────────→ Strong REST
 │
 └──────────────→ GraphQL gap
                         │
                         ▼
                GraphQL feature offered
                         │
              ┌──────────┴──────────┐
              ▼                     ▼
          Tried it              Ignored it
              │
        ┌─────┴─────┐
        ▼           ▼
     Adept       Struggled

That gives you a feedback loop:

Observe → infer gap → recommend → enable → observe outcome → update profile.


But there's a significant privacy issue

I would not design this as:

"Go to other websites and collect information about what this person can do."

Instead, design it as:

"User-authorized competency aggregation."

For example, the user explicitly connects accounts or imports their competency information.

You also need to distinguish:

Evidence

User has 27 GitHub repositories involving React.

from:

Inference

User's React competency = 4.2/5.

The second is a model-generated inference and shouldn't be presented as an objective fact.

And ideally the user should be able to see:

Why am I being recommended GraphQL?

✓ 14 REST projects detected
✓ React experience detected
✓ No GraphQL activity detected

Confidence: Medium

That makes the system explainable.

There's an even bigger research question here

You could frame the research problem as:

Can consented cross-platform competency signals be used to identify latent user capability gaps and dynamically personalize feature exposure through remote configuration?

Then you have three measurable components:

  1. Competency inference — what does the system think the user knows?

  2. Gap detection — what potentially useful capability is missing?

  3. Adaptive feature exposure — does exposing the appropriate feature actually improve adoption/competency?

Your earlier Sankey visualization could then become the evaluation mechanism showing:

User population → competency profile → detected gap → recommended feature → feature adoption → successful proficiency.

That is considerably more interesting than simply making a Sankey chart of feature usage. It starts looking like a closed-loop adaptive software system.