Programming thread

Beginner thread is so the newbie doesn't even have to worry about "shitting the thread up" with trivial BS, IMO.
i don't mind the sporadic occurrence of "hey guys how do are i am going to do the program" people because they only come by every now and then and often don't come back when they get the inevitable response of "have you tried typing the magic words on the screen" (and in the rare cases they do come back, they usually become readily-learning newbies)
having a whole dedicated thread for it seems overkill (and they never see that thread first anyway)
they are a programming thread classic and it just wouldn't be the same without them
 
im not opposed to beginners posting here as long as they are like @ChudJack009 and not "hello guys how do i learn code" because only one of them can receive help from this thread
Yes. It's never a matter of skill whether someone can post in this thread; the more the merrier. I just think we need to do something about the large number of "where do I start?" questions, and I firmly believe doing anything more than linking to the dedicated thread will only perpetuate the issue.

Edit: Obviously we don't need 10 different people replying with the link to the other thread along with some verbal abuse. There's a way to do this tactfully.
 
Last edited:
  • Feels
Reactions: Belisarius Cawl
I think trying to exclude "hay guise how 2 code?" posts would ultimately result in more noise than just one or two users reacting to them and everybody else ignoring them. After all, "Fuck off" and "Go actually try something" take the same amount of space.
 
Can you paste a complete source file that has the error with the new pad class? Might be sensible to start learning git for this and put it somewhere, that way you can just reference a specific commit for "okay this commit has this bug", while still being able to roll back to a working version at need.
Ive been using github for quite a bit and can provide a version where the pad is in use, there's no errors in the traditional sense though i feel as though you mean the fact that the bug is present and not an actual error message. In any case here's the broken version.
Python:
import curses
import sys
import os
from dataclasses import dataclass

# Shortcut Dictionary
shortcutKeys={}
def debug_buffer_to_file(buffer, filepath="debug_log.txt"):
    with open(filepath, "w", encoding="utf-8") as f:
        for i, line in enumerate(buffer):
            text_line = "".join(chr(c) for c in line)
            ascii_line = " ".join(str(c) for c in line)
            f.write(f"{i:03d}: {text_line}\n")
            f.write(f"     ASCII: {ascii_line}\n")
def window_init():
    pass

def load_file(buffer, filepath):
    """
    This function opens a file provided by the user,
    converts the lines from standard strings to a series of characetrs which are easier,
    for our buffer array to keep track of and modify.
    After converting the lines they're loaded into the buffer for modification.
    (this uses a nested for that loops through the lines array creating an ascii line array to store the asci data
    It then loops through the individual lines and converts them to their ascii numbers
    After which the ascii line array is stored in the buffer)
    """
    #[1}basic error catching system which "tries" to open a provided file

    try:
        with open(filepath, "r", encoding="utf-8")as file:
            lines = file.read().splitlines()
            for line in lines:
                ascii_line = []
                for char in line:
                    ascii_line.append(ord(char))
                buffer.append(ascii_line)

    #{2] if it cannot open the file it will print an error message and then create a blank line instead of crashing the program.

    except (FileNotFoundError, PermissionError) as e:
        print(f"[!] Could not open file '{filepath}': {e}")
        buffer.append([])        
    return buffer
           

def save_file(buffer, filepath):
    """This function opens the file provided by the user,
    Converts the lines found in the buffer back to standard strings,
    after which it writes these lines to the file and closes it"""

    content = ""
    for line in buffer:
        for column in line:
          content += chr(column)
        content += "\n"
       
    with open(filepath, "w", encoding="utf-8") as file:
        file.write(content)


def buffer_renderer(screen, buffer: list, row: int, column: int, r_offset: int, c_offset: int):
    """This function handles rendering whats in the buffer to the terminal screen.
       It loops through each row and adds a buffer row to represent it.

       If the buffer rows extend past the length of the buffer,
       it moves the screen down by a row and clears the screen.

       For each character column, offset by the horizontal scroll (c_offset),
       it tries to render the character from the buffer.
       If the buffer column is out of bounds for a given row (e.g., the line is shorter than the visible width),
       it skips rendering at that position, leaving the rest of the screen cell empty or cleared."""
   
    for rw in range(row):
            buffer_row = rw + r_offset
            if buffer_row >=len(buffer):
                screen.move(rw, 0)
                screen.clrtoeol()
                continue

            for cl in range (column):
                buffer_column = cl + c_offset
                screen.move(rw, cl)
                try:
                    screen.addch(rw, cl,buffer[buffer_row][buffer_column])
                except IndexError:
                    break
                except curses.error:
                    pass
            screen.clrtoeol()

    pass

def visual_cursor_renderer(screen, row, row_offset, column, column_offset):
        """This function handles rendering the visual cursor
        The visual cursor is the cursor found inside the terminal"""
        try:
            curses.curs_set(0)
        except curses.error:
            pass
       
        # Tell curses where to draw the visual cursor, based on scroll offset and logical cursor
        screen.move(row - row_offset, column - column_offset)

        try:
            curses.curs_set(1)
        except curses.error:
            pass

        #NOTE: This refresh might be unnecessary, will remove later
        #screen.refresh()

class StatusWindow:
    """This class will house a simple window which displays various important pieces of information about a specific file
    NOTE(
    I may want to rename this and make it also responsible for any commands I want to implement in the future
    )"""

    def __init__(self,width):
        pass


class ContentBufferWindow:
    """This class will create a curses.pad will be responsible for housing and displaying the workable area of the tezxt editor.
    NOTE(
    Ideally i want to be able to create multiple pad instances in the same manager
    )"""

    def __init__(self,  buffer, cursor, width, height):
        self.buffer = buffer
        self.cursor = cursor
        self.width = width
        self.height = height
        self.pad_height = max(len(self.buffer) + 50, self.height)
        self.pad = curses.newpad(self.pad_height, width)
   
    def content_renderer(self):
        self.pad.clear()
        for rw in range(self.pad_height):
            buffer_row = rw + self.cursor.row
            if buffer_row >=len(self.buffer):
                self.pad.move(rw, 0)
                self.pad.clrtoeol()
                continue
                #break
            for cl in range (self.width):
                buffer_column = cl + self.cursor.column
                self.pad.move(rw, cl)
                try:
                    self.pad.addch(rw, cl,self.buffer[buffer_row][buffer_column])
                except IndexError:
                    break
                except curses.error:
                    pass
            self.pad.clrtoeol()
            try:
                self.pad.refresh(
                self.cursor.row_offset,
                self.cursor.column_offset,
                0, 0,
                self.height - 1,
                self.width - 1
                )
            except curses.error:
                pass
    pass

class WorkspaceManager:
    """This class will manage:
    >>The different windows created,
    >>inputs passed
    >>Commands maybe?(not sure yet)
    >>etc(ill update as i go along)"""
    def __init__(self,):
        pass

@dataclass(slots=True)
class Cursor:
    """This class handles Cursor initialization and application.
    It needs to be aware of the cursors logical position, meaning its position within the editors buffer
    COMPONENTS:
    >> buffer         : A reference to the text buffer (a list of strings), allowing the cursor to interact with document content.
    >> row            : The current logical row index within the buffer.
    >> column         : The current logical column index within the current buffer row.
    >> row_offset     : The number of rows the screen has scrolled down from the top of the buffer; determines vertical viewport start.
    >> column_offset  : The number of columns the screen has scrolled right from the start of each line; determines horizontal viewport start.
    """

    buffer: list
    row_offset: int = 0
    row: int = 0
    column_offset: int = 0
    column: int = 0
       
    def cursor_scrolling(self, term_column, visible_rows):
        """This function takes the available column and row space and moves the visual and logical terminal between its boundries"""

        if self.column < self.column_offset:
            self.column_offset =self.column
        if self.column >= self.column_offset + term_column:
            self.column_offset = self.column - term_column +1

       
        if self.row < self.row_offset:
            self.row_offset = self.row
        if self.row >= self.row_offset + visible_rows:
            self.row_offset = self.row - visible_rows +1

    def cursor_actions(self, ch):
        """This Function takes the character recieved from getch()
        If the character is an arrow key it moves both the visual and logical cursor to the new position"""
       
        #LeftMovement
        if ch == curses.KEY_LEFT:
            if self.column !=0:
                self.column -=1
            elif self.row > 0:
                self.row -=1
                self.column = len(self.buffer[self.row])

        if ch == curses.KEY_RIGHT:
            if self.column < len(self.buffer[self.row]):
                self.column+=1
            elif self.row<len(self.buffer)-1:
                self.row +=1
                self.column = 0

       
        if ch == curses.KEY_UP:
            if self.row >0:
                self.row -=1
                #self.column = len(self.buffer[self.row])
        if ch ==curses.KEY_DOWN:
            if self.row < len(self.buffer)-1:
                self.row +=1
                #self.column = len(self.buffer[self.row])

def main(stdscr):
    # Initialize the screen
    #NOTE(
    # WILL MAKE A SPECIFIC FUNCTION FOR SCREEN INITIALIZATION
    #)

    mainscreen = stdscr            
    curses.noecho()             # Makes it so that non letter inputs arent displayed on the screen when typing
    curses.raw()                # Make it so that characters are recieved as the are sent to the terminal
    mainscreen.keypad(1)            # Enables the special keys like arrows and whatnot
   

    buffer = []

   
    src ='noname.txt'                                        # Sets the default file name
    (term_row,term_column)=mainscreen.getmaxyx()                  # Sets the terminal dimensions
    visible_rows = term_row-1                               # Sets aside a row for the line indicator/bottom info giver thingy
   
    cursor = Cursor(buffer=buffer)         # Creates and store the cursor in its own class
    content_window = ContentBufferWindow(buffer=buffer, cursor= cursor, width= term_column, height=term_row)
    # Handles file loading
    if len(sys.argv) ==2:
        src = sys.argv[1]
        load_file(buffer, src)        
    else:
        load_file(buffer, src)
   
    #NOTE(
    # Not sure i need this waiting to see if this breaks an edge case or something
    # The video i followed didnt go into great detail on why choices were made so i just keep commenting things out to text their usefullness
    # Hence large blocks of commented out code may be found all about the program thee will be removed eventually.
    #)

    while True:
        mainscreen.move(0,0)   #positions the cursor to top left

        #SCROLLING
        cursor.cursor_scrolling(term_column=term_column, visible_rows= visible_rows)


        #SCREEN RENDERING
        #buffer_renderer(screen= mainscreen, buffer=buffer, row=visible_rows, column=term_column, r_offset=cursor.row_offset, c_offset= cursor.column_offset )
        content_window.content_renderer()


        #debug_buffer_to_file(buffer=buffer)
        #STATUS BAR NOTE: Soon to be status window.
        status = f"{cursor.row+1}/{len(buffer)}  Col:{cursor.column+1}  {int((cursor.row+1)/len(buffer)*100)}%                                      {src}"
        mainscreen.addstr(term_row - 1, 0, status[:term_column-1], curses.A_REVERSE)
       
       
        #CURSOR RENDERING
        visual_cursor_renderer(screen=mainscreen, row= cursor.row, column= cursor.column, row_offset= cursor.row_offset, column_offset= cursor.column_offset)
        #screen.refresh()
       
       

        #input manager
        ch =mainscreen.getch()

        #Text insert  
        if ch != ((ch) & 0x1f) and ch < 128:
            buffer[cursor.row].insert(cursor.column, ch)
            cursor.column +=1

        #enter handling  
        if chr(ch) in "\n\r":
            line = buffer[cursor.row][cursor.column:]
            buffer[cursor.row] = buffer[cursor.row][:cursor.column]
            cursor.row+=1
            cursor.column = 0
            buffer.insert(cursor.row, line)
       
        #Backspace handling
        if ch in [8,263]:
            if cursor.column:
                cursor.column -=1
                del buffer[cursor.row][cursor.column]
            elif cursor.row>0:
                line = buffer[cursor.row][cursor.column:]
                del buffer[cursor.row]
                cursor.row -=1
                cursor.column = len(buffer[cursor.row])
                buffer[cursor.row] += line

        #CURSOR ACTIONS    
        cursor.cursor_actions(ch=ch)

       


        #NOTE: NO CLUE WHAT THIS DID, MIGHT HAVE BEEN SOME LEFT OVER CODE DEALING WITH BUFFER RENDERING
        #if cursor.row < len(buffer):
            #rw = buffer[cursor.row]
        #else:
            #None
        #rwlen = len(rw) if rw is not None else 0
        #if cursor.column >rwlen:
            #cursor.column = rwlen

        #save and quit
        if ch == (ord("s") & 0x1f):  # Ctrl+S
            save_file(buffer=buffer, filepath=src)

        if ch == (ord("q") & 0x1f):  # Ctrl+Q
            sys.exit()


curses.wrapper(main) #this protects the terminal
if you for whatever reason decide to compare the two sources you'd find that the only difference is what is and isnt commented out in the main function and main loop(namely that at line 280 the original buffer renderer is commented out and underneath is the pad renderer and at 258 the content window line is uncommented which of course creates the content window instance).
My first run hit a DivideByZero exception as I did not specify a file to edit. As a minimalist myself, I'm fine with eating an exception when I do something wrong like this, but adding a handler for the case where there is no file is helpful.

But the DEEPER problem here is that even a file with zero bytes will hit this error. I guess for the "no file name" case you'd need some logic for a default file name, so it is probably quicker to just halt-with-error on no-filename... ergo there's a case for not handling anything but the zero-size case.
this divide by zero issue is new to me because the original code had a caveat for that. theres supposed to be a default file name for when you dont enter a file but it appears that when i was refactoring i didnt account for that. Though its a simple else statement fix :
Python:
# Handles file loading
    if len(sys.argv) ==2:
        src = sys.argv[1]
        load_file(buffer, src)        
    else:
        load_file(buffer, src)
before only the if statement was present, my apologies.
what's stopping you from eschewing pads and just doing the scrolling and text printing inside the window by yourself?
potential optimization: i think curses has a function to move chunks of the window around that it can do faster than you on certain specific terminals (but it's not very important, computers are fast)
I initially handled all this myself, Pads seemed to be the most effective way to do multiple screens though ill have to look into what you're talking about
im not opposed to beginners posting here as long as they are like @ChudJack009 and not "hello guys how do i learn code" because only one of them can receive help from this thread
Responsive newbies like you are fine for this thread. New comments represent new iterations. That seems a reasonable metric for "does this belong in this thread". Beginner thread is so the newbie doesn't even have to worry about "shitting the thread up" with trivial BS, IMO.
well its nice to know im not being a nuisance, i can say that i didnt know about this beginner thread, otherwise i would have gone there from the start
Are there any projects that you would be able to recommend to me that I can learn by writing it? I wanted to at least try and reach out to people who know before I gave up.
well id suggest something in python but im biased
this is a resource i used when i wanted to get serious, its helpful if you dont know what you want to do. id suggest a workflow where you have your editor, this resource, the docs of any libraries you're currently using and your preferred llm, not necessarily to produce code for you especially since at this point you have no way of verifying if what its giving you is rubbish but to explain what documentation is saying and give clearer examples of how to use features. Python documentation is notoriously bad (he only thing i envy about rust is that their documentation feels like they want people to understand it, though ive never used rust myself). Other projects one could undergo are the 7drl challenge wich is a tutorial that allows you to complete a functioning traditional rogue like in python: https://rogueliketutorials.com/ (though id suggest this later on once you have a hang of the basics)

in all i will say if you dont want to learn youre really not going to. you have to try working on something you care about otherwise youre just going to quit when you run into problems, get a simple version of what you want together and as you learn about stuff try to incorporate it into your project. For example @Agent Snigger gave some information about memory management in python i went and did more research and decided it might be a good thing to implement in my program. now the people here mostly talk about lower level stuff like C, (lord knows i dont understand half of it) but sometimes they say things relevant to other languages and its really up to you to do your own research.
 
Edit: Obviously we don't need 10 different people replying with the link to the other thread along with some verbal abuse. There's a way to do this tactfully.
I think trying to exclude "hay guise how 2 code?" posts would ultimately result in more noise than just one or two users reacting to them and everybody else ignoring them. After all, "Fuck off" and "Go actually try something" take the same amount of space.
i feel like these people do need the hard truth and "did you know that you have to actually use your brain" quickly gets people to making an important decision, namely:
"am i going to...":
  • bust my ass for hours
  • not learn how to program today
in all i will say if you dont want to learn youre really not going to. you have to try working on something you care about otherwise youre just going to quit when you run into problems, get a simple version of what you want together and as you learn about stuff try to incorporate it into your project. For example @Agent Snigger gave some information about memory management in python i went and did more research and decided it might be a good thing to implement in my program. now the people here mostly talk about lower level stuff like C, (lord knows i dont understand half of it) but sometimes they say things relevant to other languages and its really up to you to do your own research.
you certifiably know what's up here

anyway i hope ralph can get himself a weird personal project in a randomly selected programming language and let this thread help unfuck his spaghetti, because we'll gladly take the opportunity to do it
 
Yes. It's never a matter of skill whether someone can post in this thread; the more the merrier. I just think we need to do something about the large number of "where do I start?" questions, and I firmly believe doing anything more than linking to the dedicated thread will only perpetuate the issue.

Edit: Obviously we don't need 10 different people replying with the link to the other thread along with some verbal abuse. There's a way to do this tactfully.
I agree about the tact part; my namesake is based on one of the more humane Techpriests (relatively speaking) and I would hate to see advice here become an even more autistic Stack Overflow. Having said that, the thread I made got off to a good start but then just kinda petered out. It has to compete not only with this thread but a slew of other active threads in this particular sub-forum. I really don't know what to do besides what you suggested.
 
  • Agree
Reactions: y a t s
I'm a little surprised that there's this much consensus about learners in this thread, but I ain't fightin' it. I will still shill the learner thread so a new learner can feel like they're not being disruptive to this thread, but like y'all, I'm just fine having working learners here.

language-newbies.webp
 
I'm a little surprised that there's this much consensus about learners in this thread, but I ain't fightin' it. I will still shill the learner thread so a new learner can feel like they're not being disruptive to this thread, but like y'all, I'm just fine having working learners here.

View attachment 7478126
What's the best language for learners?
 
What's the best language for learners?
Without a doubt, it's English. For whatever reason, the popular programming languages, paradigms, and documentation tend to be in American English. That being said, there's no telling what's behind the Chinese language barrier these days, but I still suspect English is the way to go. Especially since it sounds like you already know some.
 
Without a doubt, it's English. For whatever reason, the popular programming languages, paradigms, and documentation tend to be in American English. That being said, there's no telling what's behind the Chinese language barrier these days, but I still suspect English is the way to go. Especially since it sounds like you already know some.
If only you knew the legions of schizophrenic programmers to be found behind the Russian barrier.
 
I'm a little surprised that there's this much consensus about learners in this thread, but I ain't fightin' it. I will still shill the learner thread so a new learner can feel like they're not being disruptive to this thread, but like y'all, I'm just fine having working learners here.

View attachment 7478126
Gatekeeping posting to this thread with some arbitrary skill requirement is counterproductive in many ways and is just plain retarded. But it's reasonable to expect enough background knowledge to be able to ask more than just "where do I start?". Unlike language-specific or theory related questions, the discussion of where one should begin and what resources they should use will be at least 98% the same every time in essence.

Having a separate place for collecting resources that can easily be linked to in a non-condescending way saves a lot of time, effort, and space on a given page. Plus, it helps preserve such informational content in an easily accessible place instead of being peppered throughout the hundreds of pages of this thread.
 
this but unironically
C is a very simple language, and very close to the machine, which makes the person actually learn to program, preventing jeets
you should also try functional programming and perhaps a few other paradigms or you will become an irreparably brainrotted imperative nigger which is almost as bad as being a stackoverflow pasting negative iq jeet
not knowing how c works is still a crime however
 
Functional is definitely a fun challenge, makes me feel like a total retard though (Which I am - so I'm happy to push my boundaries a little). I was reading the little schemer and it was really fun and easy and then got stuck on multirember&co and have been stuck on it for a few days. I can see what I don't understand about it but still cant fully grok it, I truly feel like a stroke victim right now. Big recommend.
Also for the "other paradigms" part, there is a really nice and interesting writeup on forth on the internet: https://ratfactor.com/forth/the_programming_language_that_writes_itself.html.
 
you should also try functional programming and perhaps a few other paradigms or you will become an irreparably brainrotted imperative nigger which is almost as bad as being a stackoverflow pasting negative iq jeet
not knowing how c works is still a crime however
oh yeah, I've tried functional programming with Uiua, which is a language I've already shilled here i think. I like functional programming, because it makes me think about solving problems in a way im not used to. It's a stack based functional language, that uses symbols
Also for the "other paradigms" part, there is a really nice and interesting writeup on forth on the internet: https://ratfactor.com/forth/the_programming_language_that_writes_itself.html.
from what I know, there's a modern forth called factor
 
oh yeah, I've tried functional programming with Uiua, which is a language I've already shilled here i think. I like functional programming, because it makes me think about solving problems in a way im not used to. It's a stack based functional language, that uses symbols
it looks like apl but shittier and the demo on the website has pride flag colored symbols and prides itself on rust integration on the home page
and i refreshed it and the logo turned rainbow
it doesn't look like a functional language to me it looks more like a fagtional language
i hate everything about this please get a better taste in programming languages

i didn't even look at the language implementation because there's probably only one of them because it's a shitlang
modern forth
those do not exist, it's only a real forth if you programmed it yourself in machine code on the microprocessor
at least according to chuck
 
Last edited:
it looks like apl but shittier and the demo on the website has pride flag colored symbols
yeah, recently he added an option to turn it off
i refreshed it and the logo turned rainbow
yeah, it has a few variations of it
fagtional language
it was made by a they/them in rust
i hate everything about this please get a better taste in programming languages
the language itself is enjoyable, has built in support for many things, etc. way easier to write in than apl or bqn, as its stack based
 
Back