Hacking.py .join gone wrong

I am getting the following output.

andrewstribling@Andrews-MBP python-hacking-game % python3 andrews_hacking.py
test: This is a test for the password:  CONVERT
this is an attempt at a game row! 
[0x95e'0x95e=0x95e'0x95e,0x95e 0x95e'0x95e-0x95e'0x95e,0x95e 0x95e'0x95e.0x95e'0x95e,0x95e 0x95e'0x95e}0x95e'0x95e,0x95e 0x95e'0x95e_0x95e'0x95e,0x95e 0x95e'0x95e^0x95e'0x95e,0x95e 0x95e'0x95e)0x95e'0x95e,0x95e 0x95e00x95e,0x95e 0x95e10x95e]LIBRARY

I want it to be more like 0x95e!@CONVERT$$

where its the memory hex address, than some garbage characters outputted for a few spaces at random than the password, than the rest of the garbage characters.

def generate_game_row(game_word_set):
    hex_str = hex_number()
    # garbage character filler requires one game word
    # one game_word is obtained by calling the get_game_word function, which requires pulling information from the_game_word_set variable.
    garbage_str = garbage_character_filler(one_game_word=get_game_word(game_word_set))
    game_word_str = get_game_word(game_word_set)

    # Calculate the length of the final string
    total_length = len(hex_str) + len(garbage_str) + len(game_word_str)

    # Check if the total length is less than 16, and pad the string with garbage characters if needed
    if total_length < 16:
        remaining_length = 16 - total_length
        garbage_padding = "".join(
            random.choice(garbage_chars) for _ in range(remaining_length)
        )
        print("this is garbage_str " + garbage_str)
        print("this is game_word_str " + game_word_str)
        print("this is hex_str " + hex_str)
        return hex_str.join(garbage_str) + game_word_str + garbage_padding
    else:
        return hex_str.join(garbage_str) + game_word_str

old code

def game_row_generator(final_game_words):
    row = []
    starting_garbage_number = random.randint(2, 8)

    for i in range(starting_garbage_number):
        print(random.choice(garbage_chars), end="")
        starting_garbage_characters = row.append(random.choice(garbage_chars))

    for ending_characters in range(9 - range(row)):
        random.choice(garbage_chars),
        row.append(ending_characters)

    x = (
        starting_garbage_characters
        + str(final_game_word(game_word_set))
        + str(ending_characters)
    )
    (
        str(starting_characters)
        + str(final_game_word(game_word_set))
        + str(ending_characters)
    )
    return x


def generate_game_row(final_game_words):
    game_word_row = (
        str(hex_number())
        + str(final_game_word(final_game_words))
        + str(game_row_generator(final_game_words))
    )
    return game_word_row

Chat GPT’s fix

def generate_game_row(game_word_set):
    hex_str = hex_number()
    # garbage character filler requires one game word
    # one game_word is obtained by calling the get_game_word function, which requires pulling information from the_game_word_set variable.
    garbage_str = garbage_character_filler(one_game_word=get_game_word(game_word_set))
    game_word_str = get_game_word(game_word_set)

    # Calculate the length of the final string
    total_length = len(hex_str) + len(garbage_str) + len(game_word_str)

    # Check if the total length is less than 16, and pad the string with garbage characters if needed
    if total_length < 16:
        remaining_length = 16 - total_length
        garbage_padding = "".join(
            random.choice(garbage_chars) for _ in range(remaining_length)
        )
        print("this is garbage_str " + garbage_str)
        print("this is game_word_str " + game_word_str)
        print("this is hex_str " + hex_str)
        return hex_str.join(garbage_str) + game_word_str + garbage_padding
    else:
        return hex_str.join(garbage_str) + game_word_str

my question. isthis, is there some way to fix either of these solutions to get closer to what I want? I want to understand why the chat gpt solution is combining things on only one garbage character and not filling it in. I know my older code does the randomness well but it generates lists. my question for that code block is, how do i convert a list into a string? I keep getting error messages saying that I need to input parameters for functions but it is never ending. i spent 30 minutes filling those in, i am convinced I am in a circle of some sort.

  1. the goal of the function is to generate the memory address which starts with 0x12 some hex number. After that a random number of garbage characters from 2-8 are to be generated. After that the game word, which is always 7 characters long is to be generated, followed by garbage characters to fill out the remaining 16 slots. So for example, 0x!&SESSION%$*&@ note that the above answer is all togather in one piece and 16 characters long. this is how it should be. My answers generate the memory address, than they generate a random number of garbage characters, then they generate the password and not much else. each out put is a little different due to the ramdomizer. It seems my garbage characters are not joining the memory address properly.
# IMPORTS
import sys
import random

"""
https://inventwithpython.com/bigbookpython/project33.html
basically game_words is where I am telling python to grab the 15 words used fo the hacking mini game.

Players select from this list of words hoping to guess the password.

I need 3 words that have 0 letters in common with the password
and another 3 words that have 1,2,3,4 letters in common with the password respectivley and the password all stored in a way that python can know about it.
after that I need to make a game board that will display the characters and the words on the screen.
"""
# -----------------------------------------------------------------#

# CONSTANTS
# garbage characters system
garbage_chars = "~!@#$%^&*()_+-={}[]|;:,.<>?/"


def introduce():
    name = input("To start the game please type in your player name: ")
    print(
        f"Agent {name}! The evil dictator Kim Jong Un has decided to launch the nukes. All of humanity's hopes rest on your shoulders to hack into the system and stop the launch. You will see a series of possible words that are the password. Use our hint system software to determine if you are close to guessing the password. The hint system will tell you the letters that the word choice and the password have in common as well as positioning. You are our last hope.... \n Okay agent {name}, here are list of the possible passwords. \n Type in the word from the available list of words that you believe is the password."
    )


# this function will gather in the game words from the sevenletterwords.txt file
def get_word_list():
    with open("sevenletterwords.txt", "r") as file:
        word_list = [line.strip().upper() for line in file.readlines()]
        random.shuffle(word_list)
        # test print(full_list_of_words)
    return word_list


# This function generates a password for the player to guess.
def get_password(word_list):
    password = random.choice(word_list)
    # print("test: This is a test for the password: ", password)
    return password


# This function gets one game word from the game word list to place in the game board row.
# I want this function to randomly select one word from the game_word_set.
def get_game_word(game_word_set):
    one_game_word = random.choice(game_word_set)
    return str(one_game_word)


def hex_number():
    number = random.randint(1000, 9999)
    hex_number = hex(number)
    return hex_number


# this function will fill the game row with garbage characters.
def garbage_character_filler(one_game_word):
    garbage_row = []
    garbage_row.append(hex_number())
    garbage_placement = random.randint(2, 8)

    # we will fill the game row with a random amount of garbage characters
    for i in range(garbage_placement):
        print(random.choice(garbage_chars), end="")
        garbage_row.append(random.choice(garbage_chars))

    garbage_row.append(one_game_word)

    for ending_characters in range(9 - len(garbage_row)):
        random.choice(garbage_chars),
        garbage_row.append(ending_characters)

    result = garbage_row
    return result


# the game words need to have a certain amount of characters in common with the password.
def get_n_overlap(password, n):
    overlapping_words = []
    x = 0
    for word in word_list:
        if x < 3:
            # if the number of matching letters is the same as n than append that word to the list.
            overlap = set(password) & set(word)
            if len(overlap) == n and word != password:
                overlapping_words.append(word)
                x += 1
                if x == 3:
                    break
    return overlapping_words


# DRIVER CODE ---------------------
# these lines of code are here to prevent not defined issues.

word_list = get_word_list()
password = get_password(word_list)

# we establish a place to hold the values
game_words_dictionary = {}
game_words = []
# we can target keys in a dictionary with variables!
# I want to use this technique once I get all three of them in there.
# place the words that have 0 letters in common into the dictionary at the 0 index.
game_words_dictionary[0] = get_n_overlap(password, 0)
# now do the same things for the other words
game_words_dictionary[1] = get_n_overlap(password, 1)
game_words_dictionary[2] = get_n_overlap(password, 2)
game_words_dictionary[3] = get_n_overlap(password, 3)
game_words_dictionary[4] = get_n_overlap(password, 4)

# now we combine these values in the dictionary togather into a single list.
game_word_set = sum(game_words_dictionary.values(), [])
game_word_set.append(password)

# all of the game words are shuffled and random.shuffle will shuffle the values in place.
# alright the game words are finally established!
random.shuffle(game_word_set)
# print("This is a test for game_word_set after the shuffling occurs." + str(game_word_set))
# now I need to get the hex() number, garbage character function run, and than have the game word be put into place.
# garbage character filler requires one game word


# one game_word is obtained by calling the get_game_word function, which requires pulling information from the_game_word_set variable.
# game_row = generate_game_row(game_word_set)
# print("this is an attempt at a game row! \n" + game_row)


def main():
    rows = 16
    columns = 2
    introduce()
    # we call these functions to grab the game words list and the password.
    get_word_list()
    get_password(word_list)
    one_game_word = get_game_word(game_word_set)
    print("This is the one_game_word", one_game_word)
    garbage_character_filler(one_game_word)
    
    row_test = garbage_character_filler(one_game_word)
    result = garbage_character_filler(one_game_word)
    print("This is the result", result)


# If this program was run (instead of imported), run the game:
if __name__ == "__main__":
    try:
        main()
    except KeyboardInterrupt:
        sys.exit()  # When Ctrl-C is pressed, end the program.
# random will change things in place. there is no need for variables.

I have only skimmed through the code in your last post. There is a lot going on, so it is difficult to logically read through the code. For example, in main, you are calling some functions, but not assigning the return values to any variables. There seem to be global variables thrown in.

You say that your final output is supposed to be a 16 character long string.


Is the template supposed to be this or something different?
A hex number followed by 2-8 random characters followed by a 7 character keyword followed by as many random characters as needed to make the total length 16.


Here are a few things to consider.

Your hex_number function is generating a random integer in the range 1000-9999. For this range, the hex_number you return from this function will be a string of either 5 characters or 6 characters (because hex(1000) is '0x3e8' and hex(9999) is '0x270f', so your returned hex_number will be either 5 or 6 characters long).
With the above in mind, your goal of a 16-character long string is already a bit unclear.
Your template seems to be:
(hex number) + (2-8 random chars) + (7 char keyword) + (random chars as needed)
If your hex number is 5 or 6 characters long and the keyword has fixed length of 7, then suppose the second portion inserts 8 random chars, then you have already exceeded the 16 character limit. So, this needs some thought on your part. Do you want to start off with a 5/6 character long hex string or do you just want the first two characters '0x'? If just '0x', then that is just a fixed string and the hex_number function won’t serve any purpose. If all of the hex number, then along with the 7-char keyword, that is already 12/13 characters used up from your 16 char limit. You need to be more clear about your goal/specifications.

In your latest code, the following snippet from the garbage_character_filler function needs some clarification:

# You wrote:
garbage_placement = random.randint(2, 8)

for i in range(garbage_placement):
    print(random.choice(garbage_chars), end="")
    garbage_row.append(random.choice(garbage_chars))

garbage_row.append(one_game_word)

for ending_characters in range(9 - len(garbage_row)):
    random.choice(garbage_chars),
    garbage_row.append(ending_characters)

result = garbage_row

Here are a few questions/remarks about the above snippet?

  • What is the point of this statement in the first loop?
print(random.choice(garbage_chars), end="")

The character you print will be different from the character you actually append to garbage_row in the next statement. Perhaps, you intended to do something like:

for i in range(garbage_placement):
    garbage_char = random.choice(garbage_chars)
    print(garbage_char, end="")
    garbage_row.append(garbage_char)
  • The second loop is also rather confusing. Can you explain the logic of the second loop?
    What is the logic behind range(9 - len(garbage_row)) ?
    I am assuming at this point garbage_row is a list whose first element is a 5/6 character hex string, then there are 2-to-8 single character strings, then a 7 character keyword string, something like
    ['0x2678', '?', '(', ')', '<', 'VWXYZZZ']
    Well, you can find the number of characters pretty easily. Here are a couple of approaches:
garbage_row = ['0x2678', '?', '(', ')', '<', 'VWXYZZZ']

# Total Length = (Len of hex string) + (Number of garbage chars) + (Len of keyword)
length = len(garbage_row[0]) + len(garbage_row[1:-1]) + len(garbage_row[-1])
print(length)
# 17

# OR
length = 0
for element in garbage_row:
    length += len(element)
    
print(length)
# 17

Then you could write your second loop as:


# I chose _ as loop variable because it isn't being used in the loop body.
# If you wish, you can use i or j as the loop variable.
# limit is how long your final string is supposed to be. 
# If you want a 16 char string, then you should use 16 in place of limit.
# For length, see the earlier example.
for _ in range(limit - length):  
    garbage_char = random.choice(garbage_chars)
    garbage_row.append(garbage_char)

To join a list of strings, you can do something like:

x =  ['0x664', '{', '{', ')', 'Yellows', '@', '|', '=', '&']
y = ''.join(x)
print(y)
# "0x664{{)Yellows@|=&"

In hindsight I should have written a readme or added more comments to this code. The fact that you have to ask a question to understand shows that I need to make adjustments. I will be certain to add some lines.

Yes the plan is to have a hex number + 2-8 random characters + the password + the random characters as needed. I desire consistency in the front half of my solution.

I did not notice that the garbage character generated would be different from the print statement. Thank you for pointing that out. I have updated my code with your correction.

You pointed out that the hex() function will generate a 5-6 character memory address. I have decided to lower the range of the hex numbers from 1000-9999 to instead 1000-1500. I am praying that is enough and will test the code.

    # we will fill the game row with a random amount of garbage characters
    # random.choice will select a random garbage character from the global garbage character variable.
    # end="" will make sure that the python default of \n does not happen. 
    for i in range(garbage_placement):
        print(random.choice(garbage_chars), end="")
        garbage_row.append(random.choice(garbage_chars))

    garbage_row.append(one_game_word)

# We know that the game words are always 7 characters. We know that the game row should have 16 characters. 
    # 16-7 = 9 spaces that must be filled with the memory address and garbage characters
    # len(garbage_row will check what the remaining number of spaces are and fill them with random garbage characters)
    for ending_characters in range(9 - len(garbage_row)):
        garbage_row.append(random.choice(garbage_chars)),

    result = "".join(garbage_row)
    return result
for _ in range(limit - length):  
    garbage_char = random.choice(garbage_chars)
    garbage_row.append(garbage_char)

Your suggestion about finding a for loop to determine the loop is impressive to me because it is scalable so that if I wanted to make a harder game mode it would be able to go based off the len of things. I have added you to the credits in the readme file that I have juste created. thank you for your suggestions.

I am trying to figure out how to use this function over and over again for 16 game row lines. I am thinking I need to have a for loop = 0 and call the function to do it. but if I do it this way I need to write a conditional to make certain it does not select a word already created. Currently writing it out now.

I just wanted to update with a past of the most recent changes


import sys
import random

"""
https://inventwithpython.com/bigbookpython/project33.html
basically game_words is where I am telling python to grab the 15 words used fo the hacking mini game.

Players select from this list of words hoping to guess the password.

I need 3 words that have 0 letters in common with the password
and another 3 words that have 1,2,3,4 letters in common with the password respectivley and the password all stored in a way that python can know about it.
after that I need to make a game board that will display the characters and the words on the screen.
"""
# -----------------------------------------------------------------#

# CONSTANTS
# garbage characters system
garbage_chars = "~!@#$%^&*()_+-={}[]|;:,.<>?/"
# we establish a place to hold the values
game_words_dictionary = {}
game_words = []


def introduce():
    name = input("To start the game please type in your player name: ")
    print(
        f"Agent {name}! The evil dictator Kim Jong Un has decided to launch the nukes. All of humanity's hopes rest on your shoulders to hack into the system and stop the launch. You will see a series of possible words that are the password. Use our hint system software to determine if you are close to guessing the password. The hint system will tell you the letters that the word choice and the password have in common as well as positioning. You are our last hope.... \n Okay agent {name}, here are list of the possible passwords. \n Type in the word from the available list of words that you believe is the password."
    )


# this function will gather in the game words from the sevenletterwords.txt file
def get_word_list():
    with open("sevenletterwords.txt", "r") as file:
        word_list = [line.strip().upper() for line in file.readlines()]
        random.shuffle(word_list)
        # test print(full_list_of_words)
    return word_list


# This function generates a password for the player to guess.
def get_password(word_list):
    password = random.choice(word_list)
    # print("test: This is a test for the password: ", password)
    return password


# This function gets one game word from the game word list to place in the game board row.
# I want this function to randomly select one word from the game_word_set.
def get_game_word(game_word_set):
    one_game_word = random.choice(game_word_set)
    return one_game_word


def hex_number():
    number = random.randint(1000, 1500)
    hex_number = hex(number)
    return hex_number


# this function will fill the game row with garbage characters.
def garbage_character_filler():
    one_game_word = get_game_word(game_word_set)
    character_row_limit = 16
    garbage_row = []
    garbage_row.extend(hex_number())
    garbage_placement = random.randint(2, 8)

    for i in range(garbage_placement):
        garbage_char = random.choice(garbage_chars)
        print(garbage_char, end="")
        garbage_row.append(garbage_char)

    garbage_row.extend(one_game_word)

    # Total Length = (Len of hex string) + (Number of garbage chars) + (Len of keyword)
    length = len(garbage_row[0]) + len(garbage_row[1:-1]) + len(garbage_row[-1])

    for _ in range(character_row_limit - length):
        garbage_char = random.choice(garbage_chars)
        garbage_row.append(garbage_char)

    x = garbage_row
    y = "".join(x)
    result = garbage_row
    return result


# the game words need to have a certain amount of characters in common with the password.
def get_n_overlap(password, n):
    overlapping_words = []
    x = 0
    for word in word_list:
        if x < 3:
            # if the number of matching letters is the same as n than append that word to the list.
            overlap = set(password) & set(word)
            if len(overlap) == n and word != password:
                overlapping_words.append(word)
                x += 1
                if x == 3:
                    break
    return overlapping_words


# DRIVER CODE ---------------------
# these lines of code are here to prevent not defined issues.

word_list = get_word_list()
password = get_password(word_list)


# we can target keys in a dictionary with variables!
# I want to use this technique once I get all three of them in there.
# place the words that have 0 letters in common into the dictionary at the 0 index.
game_words_dictionary[0] = get_n_overlap(password, 0)
# now do the same things for the other words
game_words_dictionary[1] = get_n_overlap(password, 1)
game_words_dictionary[2] = get_n_overlap(password, 2)
game_words_dictionary[3] = get_n_overlap(password, 3)
game_words_dictionary[4] = get_n_overlap(password, 4)

# now we combine these values in the dictionary togather into a single list.
game_word_set = sum(game_words_dictionary.values(), [])
game_word_set.append(password)

# all of the game words are shuffled and random.shuffle will shuffle the values in place.
# alright the game words are finally established!
random.shuffle(game_word_set)
# print("This is a test for game_word_set after the shuffling occurs." + str(game_word_set))
# now I need to get the hex() number, garbage character function run, and than have the game word be put into place.
# garbage character filler requires one game word


def main():
    rows = 16
    columns = 2
    introduce()
    # we call these functions to grab the game words list and the password.
    get_word_list()
    get_password(word_list)
    one_game_word = get_game_word(game_word_set)
    garbage_character_filler()
    row_test = garbage_character_filler()
    print("\n This is garbage_character_filler called ", row_test)
    result = garbage_character_filler()


# If this program was run (instead of imported), run the game:
if __name__ == "__main__":
    try:
        main()
    except KeyboardInterrupt:
        sys.exit()  # When Ctrl-C is pressed, end the program.
# random will change things in place. there is no need for variables.

This topic was automatically closed 41 days after the last reply. New replies are no longer allowed.