Programming thread

In hindsight the correct command was:
"for i in /dev/sd* /dev/nvme* ; do dd if=/dev/zero of=$i bs=1024k & done"
end it with "; done" because potential dd errors shouldn't make the rest of the drives remain unwiped
 
  • DRINK!
Reactions: Safir
Ok Kiwis. I'm work professionally as a staff level SWE. Currently, I am working with my VP to make his fever dream into a reality. But I am struggling here. I've been asking around because I've never heard of anyone doing this. We've been hashing out the design the past few weeks and the dude is getting frustrated that "AI should make this easier."

Being deliberately vague here because the finer details don't matter all to much until we get to the fever dream part. The purpose of this application is to provide self service in our organization within the context of backend data infrastructure.
  1. User inputs some stuff.
  2. Stuff is validated against out infrastructure. This exists and so on.
  3. Application dynamically generates a variety of things. Connection configs, database DML, etc.
    1. This is where we go off the rails.
  4. Additional constraints across the organization require monitoring, source control, validation testing, etc.
  5. This must be self service so the application must meet all of these requirements and do them on its own.
  6. As we have DevOps/Infra as code/etc the application has no other choice but to create branches in multiple unrelated code repos that we do not directly own.
    1. Generate its own code files.
    2. Commit them.
    3. Push them.
    4. Create a PR for this all on its own.
I sat there explaining to the dude that this is far beyond dynamically creating some SQL DML and executing it. Now it has to follow code styling best practices, not make any errors, update multiple things in big config projects as its not just one file it has to generate. It has to make multiple necessary updates in the repo. Dynamically and in at least three different code bases of things completely unrelated to each other.

This was lost on him as he just went "durr you need to use the Azure API to do this." Well that would have been fine but you have source control for all of it as a strict requirement. Necessitating all of this. To "make it easier" he also wants to add an AI Agent to the mix to proofread the generated code if you will.

Please God help me.
 
Sadly I have not had time for learning more programming, but I decided to dust off some basic Python knowledge after some months, and attempted to do a recursive for combinations:
Python:
def x(chars, positions):
  if positions == 1:
    return [x for x in chars]

  return [a + b for a in chars for b in x(chars, positions - 1)]

print(x("1234", 3))

If someone that knows programming wants to answer, how would you do it? It has to give all combinations for the pool, for a desired length. And if someone answers, thanks in advance.
 
Sadly I have not had time for learning more programming, but I decided to dust off some basic Python knowledge after some months, and attempted to do a recursive for combinations:
Python:
def x(chars, positions):
  if positions == 1:
    return [x for x in chars]

  return [a + b for a in chars for b in x(chars, positions - 1)]

print(x("1234", 3))

If someone that knows programming wants to answer, how would you do it? It has to give all combinations for the pool, for a desired length. And if someone answers, thanks in advance.
1. This is not what a combination [with replacement] is. Combinations (with or without replacement) are sets, the order does not matter. Therefore 1,1,4 and 1,4,1 are the same item, they do not belong in one list of combinations.
1.1 You can generate all combinations, then drop repeats (or drop repeats as you generate). This is a solution, but not a good solution; ideally your code should generate a stream of valid values.
2. Does this work? You use x for the name of the function and for the iterator.
3. A copy of a list is my_list[:]. A list from an iterator is list(my_iter). You do not need [x for x in chars].
 
  • Informative
Reactions: Evil Whitey
2. Does this work? You use x for the name of the function and for the iterator.
It shadows as expected. Regardless, the ambiguity and lack of clarity is hard to ignore.

If someone that knows programming wants to answer, how would you do it? It has to give all combinations for the pool, for a desired length. And if someone answers, thanks in advance.
I think looking into power sets might be useful. The easiest way to think about it is for each element in your list/array, you have the choice of including or excluding it in a given subset. So you can pick an element to be the 1st in the list, then recursively generate subsets for each case where you either include or exclude values that follow it, and then combine those subsets into larger sets with your chosen 1st element.

So
Python:
[1, 2, 3, 4]

[1, [3, 4] # excluding 2
  , [2, 4] # excluding 3
  , [2, 3]] # excluding 4

[2, 3, 4]

[2, [4] # excluding 3
  , [3]] # excluding 4

[3, 4]

[3] # excluding 4

[4]

# some sets have been left as an exercise to the reader.
See how this can be built in the classical telescopic recursive fashion? You build the smallest sets first, then incorporate them into larger ones. You can use a recursive combining function to flatten the lists/arrays from this nested structure generated by the recursive powerset generating function.

Note that the empty set is the subset of any given set, so the power set for an empty list/array is technically not empty. Thus, the power set of the empty set is the empty set.

Edit: I posted a scheme implementation of power sets a few months ago. It's not the easiest to make sense of if you don't know lisp, but the sample output may be helpful.
I think powersets are a good exercise for learning recursion. For the fun of it, I wrote an implementation in Scheme as simply and compactly as I could:
Code:
(define (powerset s)
  (foldr (λ (x r)
           (foldr (λ (y z) (cons (cons x y) (cons y z))) '() r))
         '(()) s))

Output:
Code:
(powerset '(1 4 2 7))
'((1 4 2 7)
  (4 2 7)
  (1 2 7)
  (2 7)
  (1 4 7)
  (4 7)
  (1 7)
  (7)
  (1 4 2)
  (4 2)
  (1 2)
  (2)
  (1 4)
  (4)
  (1)
  ())

You should only need 2 simple recursive functions at most.
 
Last edited:
  • Agree
Reactions: Safir
This is not what a combination [with replacement] is. Combinations (with or without replacement) are sets, the order does not matter. Therefore 1,1,4 and 1,4,1 are the same item, they do not belong in one list of combinations.
1.1 You can generate all combinations, then drop repeats (or drop repeats as you generate). This is a solution, but not a good solution; ideally your code should generate a stream of valid values.
I think looking into power sets might be useful. The easiest way to think about it is for each element in your list/array, you have the choice of including or excluding it in a given subset. So you can pick an element to be the 1st in the list, then recursively generate subsets for each case where you either include or exclude values that follow it, and then combine those subsets into larger sets with your chosen 1st element.
That's what I meant, all possible combinations with repetition of characters (so pool ** length; for "012" with length of 3, from 000 all the way to 222; 27 possibilities).

Yeah, I should have named it something different, but as a basic exercise, seeing that it seemingly worked on the IDLE Python window, I left it as is. I'm not really working with fancy environments as a starting point for now.

I kind of looked at the powersets some months ago (I haven't touched programming in a bit), right now I don't see what my function should be dropping for all possible combinations though.

So for example for this output, you're saying that I should be dropping the last 2 characters since they were already generated, then adding them up at some point, instead of regenerating them? To make it a "good" solution.
example_1.webp
 
I've had an insanely better experience switching from C to C++ in the OCaml parsing setup I have.
Using template specialization, it was actually not terrible to make an OCaml binding scheme.
 
That's what I meant, all possible combinations with repetition of characters (so pool ** length; for "012" with length of 3, from 000 all the way to 222; 27 possibilities).

Yeah, I should have named it something different, but as a basic exercise, seeing that it seemingly worked on the IDLE Python window, I left it as is. I'm not really working with fancy environments as a starting point for now.

I kind of looked at the powersets some months ago (I haven't touched programming in a bit), right now I don't see what my function should be dropping for all possible combinations though.

So for example for this output, you're saying that I should be dropping the last 2 characters since they were already generated, then adding them up at some point, instead of regenerating them? To make it a "good" solution.
View attachment 7216041
I wrote the main half of an implementation in Scheme (mostly because doing it in Python is a pain in comparison). The logic carries over to other languages though.
Code:
(define (comb chars ln)
  (define (comb-r chars oc ln)
    (cond
      [(null? chars) '()]
      [(= ln 0) '()]
      [else (cons (cons (car chars) (comb oc (- ln 1)))
                  (comb-r (cdr chars) oc ln))]))
                
  (comb-r chars chars ln))
The idea is we can recursively iterate through the string/array/list by dropping the 1st element every time you make your next recursive call. Here, (cdr chars) is used to drop the element, but you could use chars[1:] to slice it off similarly. While we're dropping elements, we still want to keep track of the original set we started with. That's what the oc variable I use is for. If this code makes no sense at a glance, don't worry. That's lisp in a nutshell.

The most important part is what we're doing here is generating a tree of possible values for each position:
Code:
(comb '(1 2 3 4) 3)

Output:
'((1 (1 (1)
        (2)
        (3)
        (4))
     (2 (1)
        (2)
        (3)
        (4))
     (3 (1)
        (2)
        (3)
        (4))
     (4 (1)
        (2)
        (3)
        (4)))
  (2 (1 (1)
        (2)
        (3)
        (4))
     (2 (1)
        (2)
        (3)
        (4))
     (3 (1)
        (2)
        (3)
        (4))
     (4 (1)
        (2)
        (3)
        (4)))
  (3 (1 (1)
        (2)
        (3)
        (4))
     (2 (1)
        (2)
        (3)
        (4))
     (3 (1)
        (2)
        (3)
        (4))
     (4 (1)
        (2)
        (3)
        (4)))
  (4 (1 (1)
        (2)
        (3)
        (4))
     (2 (1)
        (2)
        (3)
        (4))
     (3 (1)
        (2)
        (3)
        (4))
     (4 (1)
        (2)
        (3)
        (4))))
All you have to do with this reassemble the characters into strings by choosing each given element, working from right to left. I hope at least seeing this tree-like structure of Scheme's list output will help you visualize how to handle this problem.
 
Last edited:
Ok Kiwis. I'm work professionally as a staff level SWE. Currently, I am working with my VP to make his fever dream into a reality. But I am struggling here. I've been asking around because I've never heard of anyone doing this. We've been hashing out the design the past few weeks and the dude is getting frustrated that "AI should make this easier."

Being deliberately vague here because the finer details don't matter all to much until we get to the fever dream part. The purpose of this application is to provide self service in our organization within the context of backend data infrastructure.
  1. User inputs some stuff.
  2. Stuff is validated against out infrastructure. This exists and so on.
  3. Application dynamically generates a variety of things. Connection configs, database DML, etc.
    1. This is where we go off the rails.
  4. Additional constraints across the organization require monitoring, source control, validation testing, etc.
  5. This must be self service so the application must meet all of these requirements and do them on its own.
  6. As we have DevOps/Infra as code/etc the application has no other choice but to create branches in multiple unrelated code repos that we do not directly own.
    1. Generate its own code files.
    2. Commit them.
    3. Push them.
    4. Create a PR for this all on its own.
I sat there explaining to the dude that this is far beyond dynamically creating some SQL DML and executing it. Now it has to follow code styling best practices, not make any errors, update multiple things in big config projects as its not just one file it has to generate. It has to make multiple necessary updates in the repo. Dynamically and in at least three different code bases of things completely unrelated to each other.

This was lost on him as he just went "durr you need to use the Azure API to do this." Well that would have been fine but you have source control for all of it as a strict requirement. Necessitating all of this. To "make it easier" he also wants to add an AI Agent to the mix to proofread the generated code if you will.

Please God help me.
Question, can the application generate a binary that encapsulates all these changes and is shared via a package management repository (NuGet, pip, etc.) and then make a PR that just updates the version of the binary?

That would reduce the insanity of having a code generator just shitting into random repos and then the actual code would only need to adhere to whatever conventions are relevant to what is exposed to the consuming codebases.

I created a mission-critical component consumed by multiple products which is essentially a visual coding UI that powers all of our decisioning. It generates a compiled binary and then an agent in each application syncs that to all of the consuming application containers, loading it in dynamically and replacing the previous version.

I'm not saying that part would address your needs but it's an example of providing the individual applications with enough awareness to allow them to consume the dynamically-generated artifact while centralizing the logic for generating it.

Obviously we have extensive test coverage of all the functionality for editing, compiling, and executing the binary in the context of a consuming application because having it fail at execution time is not acceptable, which would be the kind of thing that what you described wouldn't necessarily require because if it's going to fail it's probably going to be in the build pipeline.

Also, remember the "Fundamental theorem of software engineering":
"We can solve any problem by introducing an extra level of indirection."
 
Last edited:
  • Like
Reactions: y a t s
guys did you know that cl.exe still doesnt support VLA's? a C99 standard feature?

also windows requires some macro fuckery so that i can open files named with wide string characters
im doing something like this, idk if there's a better way
C:
#if defined(WIN_32)
#define FILENAME_CHAR_TYPE wchar_t
#define FILENAME_STRING(str) L##str
#define FILENAME_OPEN_FILE _wfopen
#else
#define FILENAME_CHAR_TYPE char
#define FILENAME_STRING(str) str
#define FILENAME_OPEN_FILE fopen
#endif
 
also windows requires some macro fuckery so that i can open files named with wide string characters
There will come a day when you're doing something incredibly simple in C/C++, and you're trying to do debug prints. Nothing will fucking show up. You'll tear your hair out for a good few hours until you find out about windows and UTF-16.
 
guys did you know that cl.exe still doesnt support VLA's? a C99 standard feature?
Good. Most retarded feature ever conceived.
also windows requires some macro fuckery so that i can open files named with wide string characters
im doing something like this, idk if there's a better way
C:
#if defined(WIN_32)
#define FILENAME_CHAR_TYPE wchar_t
#define FILENAME_STRING(str) L##str
#define FILENAME_OPEN_FILE _wfopen
#else
#define FILENAME_CHAR_TYPE char
#define FILENAME_STRING(str) str
#define FILENAME_OPEN_FILE fopen
#endif
Better way is to stick with CreateFile with windows.
 
guys did you know that cl.exe still doesnt support VLA's? a C99 standard feature?
Neither does any other (standard) C++ compiler.

Microsoft's support for C extends to the standard library, not language features. You'll find that _Complex is missing too.
 
Back