10 votes

Fortnightly Programming Q&A Thread

General Programming Q&A thread! Ask any questions about programming, answer the questions of other users, or post suggestions for future threads.

Don't forget to format your code using the triple backticks or tildes:

Here is my schema:

```sql
CREATE TABLE article_to_warehouse (
  article_id   INTEGER
, warehouse_id INTEGER
)
;
```

How do I add a `UNIQUE` constraint?

8 comments

  1. [4]
    Apos
    (edited )
    Link
    Let's say I have a world where I can put rectangles in any arbitrary location. The rules are the following: After inserting a new rectangle, no rectangle should be overlapping each others If an...

    Let's say I have a world where I can put rectangles in any arbitrary location. The rules are the following:

    1. After inserting a new rectangle, no rectangle should be overlapping each others
    2. If an overlap happens, rectangles should be split and / or resized such that their verticality is maximized and cover the full area that the rectangles covered (not sure how to explain it better than that but it should be easier to understand from the examples)
    3. If two rectangles next to each others have the same verticality, they should be merged

    Here are some examples of what I mean. The gray rectangles show the initial state. The transparent green rectangle shows the rectangle being inserted. The blue rectangles shows the newly inserted rectangles after running the algorithm.

    Example 01:

    1. Initial state 2 rectangles
    2. Insertion
    3. Final state 5 rectangles

    Example 02:

    1. Initial state 2 rectangles
    2. Insertion
    3. Final state 3 rectangles

    Example 03:

    1. Initial state 1 rectangle
    2. Insertion
    3. Final state 3 rectangles

    Example 04:

    1. Initial state 1 rectangle
    2. Insertion
    3. Final state 1 rectangle

    Example 05:

    1. Initial state 2 rectangles
    2. Insertion
    3. Final state 1 rectangle

    Example 06:

    1. Initial state 1 rectangle
    2. Insertion
    3. Final state 3 rectangles

    Example 07:

    1. Initial state 2 rectangles
    2. Insertion
    3. Final state 2 rectangles

    Example 08:

    1. Initial state 1 rectangle
    2. Insertion
    3. Final state 1 rectangle

    Originally, I was using a brute force approach that stored every rectangle. Every time a new rectangle was added I'd discard these "vertical" rectangles and recompute the whole world. This time though I'm looking for a way to only update locally the rectangles that should change around where the new rectangle is added. Visually, the solution seems obvious, but I can't come up with the right algorithm that's as simple to implement as it looks.

    (Eventually I'd also like to do rectangle removal or updating, but for now adding is enough.)

    Edit: Fixed an issue with example 02. I had missed the rule 3 where I should merge vertically similar rectangles next to each others. snip

    5 votes
    1. [3]
      Moonchild
      Link Parent
      Look into forms of space partitioning like bsp or quadtrees. Those let you quickly identify which nodes your newly added rectangle overlaps with, and only look at rectangles within those nodes.

      Look into forms of space partitioning like bsp or quadtrees. Those let you quickly identify which nodes your newly added rectangle overlaps with, and only look at rectangles within those nodes.

      3 votes
      1. Apos
        Link Parent
        Indeed, I can do a quick query with that, but I was thinking more about the merging itself. But I think I was overthinking it. I just came up with 8 rules that I think will solve this problem. Not...

        Indeed, I can do a quick query with that, but I was thinking more about the merging itself. But I think I was overthinking it. I just came up with 8 rules that I think will solve this problem. Not sure if there are mistakes, but I'll try to code this tomorrow:

        To add to verticals:

        1. Create new vertical (a). Add it to the pending list.
        2. Query existing verticals at that position.
        3. For each vertical:
          1. If vertical fully contains (a), done.
          2. If (a) fully contains vertical, remove vertical.
          3. If vertical matches (a)'s height, remove it. Expand (a) to cover removed vertical.
          4. If (a) pokes vertical vertically, split vertical. Expand (a) to match vertical's top or bottom based on which way it pokes.
          5. If (a) pokes vertical horizontally, shrink (a) to end on the left or right edge of vertical.
          6. If (a) stabs vertical vertically, split vertical, shrink to the left and / or right side of (a).
          7. If (a) stabs all the way through vertical horizontally, split (a), shrink to the left and right of vertical. Add each nodes to the pending list.
          8. If (a) overlaps vertical slightly, split (a), expand part that overlaps vertical, expand vertical if both sides overlap. Add each nodes to the pending list.
        4. Add pending list to vertical.

        Made up a bunch of words. Should be fun to implement that.

        2 votes
      2. Apos
        Link Parent
        In this end this is what I got which is much simpler than the other thing I wrote in my other reply: Let's say I want this, what I do is for each rectangle, I dissect them into two vertical range,...

        In this end this is what I got which is much simpler than the other thing I wrote in my other reply:

        Let's say I want this, what I do is for each rectangle, I dissect them into two vertical range, one on the left of the rectangle and one on the right. The ranges on the same X axis are considered part of the same slab. I merge overlapping ranges. I sweep through those slabs one by one from left to right. Each time a previous slab doesn't have a matching range, a new vertical rectangle is created.

        Another example: this becomes this.

        I got a first implementation done. It's not yet super optimized, but it seems to work really well.

        1 vote
  2. [4]
    knocklessmonster
    (edited )
    Link
    I'm working on a simple guess-style game in which I generate an array of letters, guess a sequence, test the sequence against the generated sequence, and display a message showing what is...

    I'm working on a simple guess-style game in which I generate an array of letters, guess a sequence, test the sequence against the generated sequence, and display a message showing what is right/wrong.

    I'm stuck at passing the array from one object to another, and am also unsure how to do it without regenerating the array each run.

    I've got my code below.

    import sys;
    import random
    
    CHOOSE_ARRAY = ["a","b","c","d"]
    
    # Generate array for the game
    
    class GameArray:
        def __init__(self):
            self.gameArray = []
        def genArray(self):
            i = 1
            while i <= 4:
                self.gameArray.append(random.choice(CHOOSE_ARRAY))
                i += 1
            return self.gameArray
    
    # Get user input for test array
    
    class ArrayInput:
        def __init__(self):
            self.testArray = []
        def getArray(self):
            print("Please input letters from a to b")
            self.testArray.append(input("Input the first letter:>> "))
            self.testArray.append(input("Input the second letter:>> "))
            self.testArray.append(input("Input the third letter:>> "))
            self.testArray.append(input("Input the fourth letter:>> "))
        def useArray(self):
            return self.testArray
    
    #instantiate GameArray()
    game = GameArray()
    
    #instantiate ArrayInput, get input
    user = ArrayInput()
    user.getArray()
    
    # ensure I'm generating arrays
    print(game.genArray())
    print(user.useArray())
    

    When doing something like this, I like to print the output so I can actually determine that the data is what I expect it to be. Would the best way for me to get the data in GameArray.genARray from GameArray to ArrayInput be to design it so I call something like ArrayInput.(GameArray.genArray)? My comparison, AFAIK, will be done via for loops against the arrays (sort of fizzbuzz style lazy test), but I'm clueless on how to get the data where I need it to start doing testing like that.

    3 votes
    1. [3]
      DataWraith
      (edited )
      Link Parent
      To me, using separate objects for everything seems like total overkill. Your objects are wrapping Lists, but you can just use normal functions on Lists without involving objects. I'd suggest the...

      To me, using separate objects for everything seems like total overkill. Your objects are wrapping Lists, but you can just use normal functions on Lists without involving objects. I'd suggest the following solution:

      import random
      
      CHOOSE_ARRAY = ["a", "b", "c", "d"]
      
      def make_code(length = 4):
          # Choose `length` times from CHOOSE_ARRAY, with replacement
          return random.choices(CHOOSE_ARRAY, k = length)
      
      def get_guess():
          # Convert the user input into a list of characters
          return list(input("Input your guess: "))
      
      def compare_guess(code, guess):
          pass # (see spoiler tag)
      
      code = make_code()
      #print(code) # (uncomment for debugging)
      guess = get_guess()
      print("You guessed:  ", guess)
      print("Result:       ", compare_guess(code, guess))
      print("The code was: ", code)
      

      You can add a loop around the last four lines if you want the player to be able to guess multiple times. Since the code is saved in its own variable, it won't change after a guess.

      If you still need to pass something from object to object, you can define a method that takes the thing you want to pass in as an argument:

      class Game:
          [...]
          def use_thing(self, thing):
             # Make use of thing
      
      Spoiler
      def compare_guess(code, guess):
          result = []
          for (code_char, guess_char) in zip(code, guess):
              if code_char == guess_char:
                  result.append("✓")
              else:
                  result.append("✘")
          return result
      
      1 vote
      1. [2]
        knocklessmonster
        (edited )
        Link Parent
        Definitely, but I wanted to do something of an intro to Python OOP with this project, and it felt like a good way to wrap my head around it. Looking at what you wrote, I did things a little...

        To me, using separate objects for everything seems like total overkill.

        Definitely, but I wanted to do something of an intro to Python OOP with this project, and it felt like a good way to wrap my head around it.

        Looking at what you wrote, I did things a little different because I had to define the inputs on the Game class. I had to create a new class, add the inputs, then use a method to add the inputs to the new class:

        class Game(GameArray, ArrayInput):
            def playGame(self, gameArray, testArray):
                self.gameArray = gameArray
                self.testArray = testArray
            def testGameArray(self):
                print(self.gameArray)
            def testTestArray(self):
                print(self.testArray)
        

        Putting it all together, I was able to determine everything is going to the objects it needs to:

        user = ArrayInput()
        user.getArray()
        
        print(game.genArray())
        print(user.useArray())
        
        runGame = Game()
        runGame.playGame(game.gameArray, user.testArray)
        runGame.testGameArray()
        runGame.testTestArray(
        

        and got the right outputs, the first of each pair being generated, and the second of each pair being inputted:

        ['c', 'd', 'b', 'b']
        ['a', 'd', 'b', 'c']
        ['c', 'd', 'b', 'b']
        ['a', 'd', 'b', 'c']
        

        Thanks for the heads up about looping, I was going to do it that way anyway, and wanted to pass the data properly first.

        2 votes
        1. DataWraith
          Link Parent
          I'm glad you found something that works. :) I'm just slightly confused by the design. You're making Game a sub-class of both GameArray and ArrayInput, and that means that it can do both genArray()...

          I'm glad you found something that works. :)

          I'm just slightly confused by the design. You're making Game a sub-class of both GameArray and ArrayInput, and that means that it can do both genArray() and getArray() -- you don't need a separate user ArrayInput anymore, you can just do game.{get,use}Array().

          But it seems... messy to my sensibilities, because Game is now doing multiple things and things get shoved into it from the outside via the playGame method (which is a bit confusing itself, because it does not play the game, it just prepares it).

          If you're interested in further advice: I think it would be better to separate things cleanly into their concerns (without sub-classing), namely (a) making/breaking the puzzle and (b) reading player input.

          I would make a class Puzzle that generates a random code to break in __init__ and does not concern itself with player input. Then you can add methods to that class that only pertain to checking the puzzle's code. For example, one method could calculate the number of black pegs (given a guess as input), one the number of white pegs, and one whether or not the code was cracked (i.e. 4 black pegs). This encapsulates the knowledge about the code(-breaking) in one place and would allow for a relatively simple game loop that does not know anything about the puzzle internals and only concerns itself with gathering user input and forwarding it.

          1 vote