So I have a file "game.txt" which consist of an instruction and a number. The instruction is either "coin," "jump," or "none." "Coin" stores the number following the instruction, "jump" will jump to a new instruction relative to itself and do whatever that instructions says, and "none" will do nothing. However, "jump +2" would continue to the instruction two lines below, and "jump -5" causes the instruction 5 lines above to be executed next.
I want to be able to iterate through the file, write the number on a new file, and count how many "coins" there are at the end. I already have a decent function that gets me somewhat close to this, but I have some bugs that I can't seem to figure out.
ex.)
I have 533 as my total, but only 528 entries in my new file
I would also like to simplify the code if possible (looks redundant in some parts)
game.txt file game.txt file link
def counting_coins(file):
count = 0
game_list = [] # list of all game steps
valid_coins = [] # list of all coin values
try:
coins = open("coins.txt", "x")
except FileExistsError:
coins = open("coins.txt", "w") # if file already exists
with open(file, "r") as cc:
### LOOPS ###
for line in cc:
game_list.append(line[0:-1]) # append each line to list to index and iterate
for i in range(len(game_list)):
current = game_list[i] # keep track of current step
if "coin" == current[0:4]:
count += 1
if game_list[i][5:6] == "+":
valid_coins.append(current[6:] + "\n")
# count += 1
elif game_list[i][5:6] == "-":
valid_coins.append("-" + current[6:] + "\n")
# count += 1
elif "jump" == current[0:4]:
if current[5:6] == "+":
num = int(current[6:])
jump = game_list[i + num]
elif current[5:6] == "-":
num = int(current[6:])
num = -num
jump = game_list[i + num]
if "coin" == jump[0:4]:
count += 1
if jump[5:6] == "+":
valid_coins.append(jump[6:] + "\n")
# count += 1
elif jump[5:6] == "-":
valid_coins.append("-" + jump[6:] + "\n")
# count += 1
elif "jump" == jump[0:4]:
if jump[5:6] == "+":
new_num = int(jump[6:])
new_jump = game_list[(i + num) + new_num]
elif jump[5:6] == "-":
new_num = int(jump[6:])
new_num = -new_num
new_jump = game_list[(i + num) + new_num]
if "coin" == new_jump[0:4]:
count += 1
if new_jump[5:6] == "+":
valid_coins.append(new_jump[6:] + "\n")
# count += 1
elif new_jump[5:6] == "-":
valid_coins.append("-" + new_jump[6:] + "\n")
# count += 1
elif "jump" == new_jump[0:4]:
if new_jump[5:6] == "+":
new_num2 = int(new_jump[6:])
new_jump2 = game_list[(i + num) + new_num + new_num2]
elif new_jump[5:6] == "-":
new_num2 = int(new_jump[6:])
new_num2 = -new_num2
new_jump2 = game_list[(i + num) + new_num + new_num2]
if "coin" == new_jump2[0:4]:
count += 1
if new_jump2[5:6] == "+":
valid_coins.append(new_jump2[6:] + "\n")
# count += 1
elif new_jump2[5:6] == "-":
valid_coins.append("-" + new_jump2[6:] + "\n")
# count += 1
elif "none" == current[0:4]:
continue
for i in range(len(valid_coins)):
if valid_coins[i] == valid_coins[-1]: # if last entry
coins.write(valid_coins[i][:-1]) # removes preceding newline
else:
coins.write(valid_coins[i])
coins.close()
return coins, count
file, count = counting_coins("game.txt")
print(f"Total coins collected: {count}")
Don't use all those nested if statements for jumping. Just reset the current index of the main loop to the element that you're jumping to.
You'll need to use a while loop instead of looping over range() so you can reset the index.
Instead of all that slicing, use split() to split each line into a command and argument.
i = 0
while i < len(game_list):
current = game_list[i].split()
if current[0] == "coin":
count += 1
valid_coins.append(current[1])
elif current[0] == "jump"
i += int(current[1])
elif current[0] = "none":
pass
else:
print(f"invalid line {game_list[i]}")
with open("coins.txt", "w") as coins:
coins.write("\n".join(valid_coins))
There's no need for the try/except. Opening in w mode will create the file if it doesn't already exist, you don't need x for that.
Related
My Problem is on line 25 when it says
if conformation == 1:
for i in range(l, len(lines[k]), 1):
if lines[k][i].isdigit() or lines[k][i].istitle():
f += lines[k][i]
if f in var:
print(var[f])
What my issue is is that the "f" string isn't being added to and its value stays as "". For context, I'm trying to make my own sort of mini programming language, and I'm trying to make prints read for variables. Every time it loops to set f to the variable name, nothing happens. The only way I get remotely close to finding the variable name is by doing "print(lines[k][i])" before the "if lines[k][i]" condition.
Note: I was using a debugger, and I'm not sure if the "if f in var" condition is even being checked.
Python code that reads my custom programming language:
⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄
code = open("HelloWorld.sabo", 'r')
lines = code.readlines()
var = {}
for k in range(0, len(lines), 1):
conformation = 0
temp = ""
temp2 = ""
if lines[k][0:5] == "print":
r = 0
l = 0
p = False
f = ""
for i in lines[k]:
r += 1
if not p:
l += 1
if i == "(":
p = True
conformation += 1
if i == "\"" and conformation == 1:
conformation += 1
if conformation == 2:
break
if conformation == 1:
for i in range(l, len(lines[k]), 1):
if lines[k][i].isdigit() or lines[k][i].istitle():
f += lines[k][i]
if f in var:
print(var[f])
if conformation == 2:
for i in range(r, len(lines[k]), 1):
if not lines[k][i] == "\"":
f += lines[k][i]
else:
break
print(f)
elif lines[k][0:4] == "var ":
for i in range(4, len(lines[k]), 1):
if not lines[k][i] == " ":
temp += lines[k][i]
else: break
for i in range(4, len(lines[k])):
if lines[k][i] == "=":
conformation = 1
elif conformation == 1:
if not lines[k][i] == " ":
temp2 += lines[k][i]
elif not temp2 == "":
break
var[temp] = temp2.strip()
Code that is being read by the above script:
⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄
var val = hello
print(val)
So, I was being a bit dumb with this, but I found out that if I just account for Uppercase and Lowercase characters, then it will work.
if lines[k][i].islower() or lines[k][i].isdigit() or lines[k][i].isnumeric() or lines[k][i].istitle():
f += lines[k][i]
I might have gone overboard with the security though I'm just not sure about the difference isdigit and isnumeric.
I have created the following pop function:
def pop(arr):
if not isempty(arr):
topelement = arr[len(arr)-1]
arr.remove(topelement)
return topelement
And it worked correctly until I used it in order to reverse order of a stack of numbers and operators:
"3 6 2 + * 14 3 4 + + /"
into
"/ + + 4 3 14 * + 2 6 3".
In first iteration of while loop shown below it pushed "/" operator to the auxiliary stack and deleted it from the top of entry, which is OK - but in the second iteration it deleted "+" sign from the middle of the entry instead of the plus sign with the highest index.
def evaluation(eq):
entryunsplit = errpostfix(eq)
entry = entryunsplit.split()
lengthofentry = len(entry)
stack = []
while len(stack) != lengthofentry:
push(stack,pop(entry))
Could someone please explain me why didn't it delete the last element and how can I avoid that error?
I am putting the whole code below in case some other element turns out to be significant.
stack1 = []
max_size = 30
def push(arr,a):
if len(arr) < max_size:
arr.append(a)
def isempty(arr):
if len(arr) == 0:
return True
else:
return False
def top(arr):
if not isempty(arr):
return arr[len(arr)-1]
def pop(arr):
if not isempty(arr):
topelement = arr[len(arr)-1]
arr.remove(topelement)
return topelement
def errpostfix(eq):
entry = eq.split()
opstack = []
exit = []
priorities = { "+": 1, "-": 1, "*": 0, "/": 0 }
for token in entry:
if token == "(":
push(opstack,token)
elif token == "*" or token == "/" or token == "+" or token == "-":
if top(opstack) == "*" or top(opstack) == "/" or top(opstack) == "+" or top(opstack) == "-":
while not isempty(opstack) and priorities[top(opstack)] >= priorities[token]:
push(exit,pop(opstack))
isempty(opstack)
push(opstack,token)
elif token == ")":
while top(opstack) != "(":
push(exit,pop(opstack))
pop(opstack)
else:
push(exit,token)
while not isempty(opstack):
push(exit, pop(opstack))
output = " ".join(exit)
return output
def isop(ch):
if ch == "+" or ch == "-" or ch == "*" or ch == "/":
return True
else:
return False
def evaluation(eq):
entryunsplit = "3 6 2 + * 14 3 4 + + /"
entry = entryunsplit.split()
lengthofentry = len(entry)
stack = []
while len(stack) != lengthofentry:
push(stack,pop(entry))
The remove() operation on a list will delete the first occurrence of an item in that list, is not "random" (check the docs). If there are several repeated elements, the first one encountered will be the one that gets deleted. To delete the last element, simply use the built-in pop() method:
def pop(arr):
if not isempty(arr):
topelement = arr[-1]
arr.pop()
return topelement
With the display I want the Banking command: input to start on a new string but when it gets to the display elif it does not. I know why, its because of the end= '' but I need to have the display be in one line for the assignment and I cant figure out a solution. Thanks for the help.
def main():
number_of_accounts = int(input("Number of accounts:\n"))
accounts = [0.0] * number_of_accounts
banking_command(accounts)
def banking_command(accounts):
from os import _exit as exit
active = True
while active:
banking_command = input('Banking command:\n')
banking_command = banking_command.split(' ')
if banking_command[0] == 'add':
monetary_amount = float(banking_command[2])
account_being_changed = int(banking_command[1])
accounts[account_being_changed - 1] += monetary_amount
elif banking_command[0] == 'subtract':
monetary_amount = float(banking_command[2])
account_being_changed = int(banking_command[1])
accounts[account_being_changed - 1] -= monetary_amount
elif banking_command[0] == 'move':
monetary_amount = float(banking_command[3])
transfer_money_out = int(banking_command[1])
transfer_money_in = int(banking_command[2])
accounts[transfer_money_out - 1] -= monetary_amount
accounts[transfer_money_in - 1] += monetary_amount
elif banking_command[0] == 'display':
i = 0
while i < len(accounts):
account_number = i + 1
print(str(account_number) + ":$" + str(accounts[i]) + " ", end= '')
i += 1
elif banking_command[0] == 'exit':
exit(0)
main()
Add a print() after the while loop.
elif banking_command[0] == 'display':
i = 0
while i < len(accounts):
account_number = i + 1
print(str(account_number) + ":$" + str(accounts[i]) + " ", end= '')
i += 1
print() # <-- end the line with the account display
So I'm attempting to make a Brainfuck interpreter, however in the while loop that I am using to execute the Brainfuck loop, it is breaking out even though only one condition is true.
Example:
+++[>+<-]
Should result in:
[0, 3]
However, when the loop begins at [, it will create a new cell so the structure goes from [3] to [3, 0]. Thus, the current working cell is 0 and the loop is breaking out. However, I have it to only break if it is 0 and the current character is ].
cells = [0] # Array of data cells in use
brainfuck = str(input("Input Brainfuck Code: ")) # Brainfuck code
workingCell = 0 # Data pointer position
count = 0 # Current position in code
def commands(command):
global cells
global workingCell
if command == ">":
workingCell += 1
if workingCell > len(cells) - 1:
cells.append(0)
elif command == "<":
workingCell -= 1
elif command == "+":
cells[workingCell] += 1
elif command == "-":
cells[workingCell] -= 1
elif command == ".":
print(chr(cells[workingCell]))
elif command == ",":
cells[workingCell] = int(input("Input: "))
def looper(count):
global cells
global workingCell
print("START LOOP", count)
count += 1
looper = loopStart = count
while brainfuck[looper] != "]" and cells[workingCell] != 0: # This line is causing trouble
if brainfuck[looper] == "]":
looper = loopStart
commands(brainfuck[looper])
count += 1
looper += 1
return count
while count < len(brainfuck):
if brainfuck[count] == "[":
count = looper(count)
print("END LOOP", count)
else:
commands(brainfuck[count])
count += 1
Thank you in advance.
I have it to only break if it is 0 and the current character is ]
If that's what you want, you have the logic in your while wrong. It should be:
while not (brainfuck[looper] == "]" and cells[workingCell] == 0):
And according to deMorgan's Laws, when you distribute not across and, you invert each of the conditions and change and to or, so it should be:
while brainfuck[looper] != "]" or cells[workingCell] != 0:
If this is confusing, you could just write:
while True:
if brainfuck[looper] == "]" and cells[workingCell] == 0:
break
This mirrors what you said in the description exactly.
So yes I know that there is an answer on how to fix this but can someone explain to me what the hell it means?Because I don't know where it comes from and I also don't know what indented means in programming (as you can understand dear reader English is not my native tongue).
P.S I found that error from a for-loop I was trying to execute, and the code was similar to this:
img = img.resize((basewidth,hsize), PIL.Image.ANTIALIAS)
j='.jpg'
s='somepic'
p=img.save(s+'1'+j)
for i in range(2, 659):
if i==21:
i = i + 1
elif i==36:
i=i+1
elif i==45:
i = i + 1
elif i==51:
i = i + 1
elif i==133:
i = i + 1
elif i==163:
i = i + 1
elif i==263:
i = i + 1
elif i==267:
i = i + 1
elif i==272:
i = i + 1
elif i==299:
i = i + 1
elif i==300:
i = i + 1
elif i==312:
i = i + 1
elif i==313:
i = i + 1
elif i==314:
i = i + 1
elif i==320:
i = i + 1
elif i==323:
i = i + 1
elif i==362:
i = i + 1
elif i==390:
i = i + 1
elif i==432:
i = i + 1
elif i==445:
i = i + 1
elif i==455:
i = i + 1
elif i==459:
i = i + 1
elif i==460:
i = i + 1
elif i==461:
i = i + 1
elif i==477:
i = i + 1
elif i==487:
i = i + 1
elif i==493:
i = i + 1
elif i==496:
i = i + 1
elif i==500:
i = i + 1
elif i==510:
i = i + 1
elif i==519:
i = i + 1
elif i==522:
i = i + 1
elif i==545:
i = i + 1
elif i==547:
i = i + 1
elif i==562:
i = i + 1
elif i==597:
i = i + 1
elif i==599:
i = i + 1
elif i==615:
i = i + 1
elif i==638:
i = i + 1
elif i==654:
i=i+1
else:
p= img + "i".save(s+i+j)
i=i+1
Which means a for-loop, an if-statement, a couple of elifs (or ORs inside the first if-statement) and then I am closing my if-statement with a save and a step forward.
EDITED: So the code above is what I have written and before that are a bunch of image inputs.But although I manage to fix the code with what you said at the end I have another error which says ['str' object has no attribute 'save'] but that is a problem for another time.
In python syntax, if statements, loops, and functions must be followed by indented lines. It's just python syntax. You have to put 4 spaces or use a tab before each line to indent them. In many other scripting languages, { } are used to enclose the code blocks. Without correct indenting, python doesn't know when a block of code ends.
An indent in Python is 4 spaces. Would have commented this, but I don't have enough reputation. Here's a link: Python: using 4 spaces for indention. Why?