Why is the "f" string not changing - python

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.

Related

Trying to Iterate Through File and Having Issues

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.

Runtime error when submitting Kattis problem in python: I can guess the data structure

I'm trying for a while now to submit my solution to the following problem on Kattis: I can guess the data structure!. However, I keep getting a runtime error; I cannot think of anywhere it can go wrong since it works with all my input. Here is my solution:
import heapq, sys
def throwin(q,s,h,x, results):
if results[0]:
q.append(x)
if results[1]:
s.append(x)
if results[2]:
heapq.heappush(h, -x)
return (q,s ,h )
def printstructures(l):
for j in l:
if j[0] and j[1] or j[0] and j[2] or j[1] and j[2]:
print("not sure")
elif not j[0] and not j[1] and not j[2]:
print("impossible")
elif j[0]:
print("queue")
elif j[1]:
print("stack")
else:
print("priority queue")
def main():
results_global = []
stackops = []
current = []
while True:
try:
line = input()
if len(line) == 1:
if len(current) != 0:
stackops.append(current)
current = []
else:
current.append(tuple(map(int, line.split(" "))))
except EOFError:
break
stackops.append(current)
for op in stackops:
q,s,h = [],[],[]
heapq._heapify_max(h)
results = [True, True, True]
for i in range(len(op)):
o, x = op[i]
if o == 1:
q,s,h = throwin(q,s,h,x, results)
else:
if len(q) == 0 or q[0] != x:
results[0] = False
else:
q.pop(0)
if len(s) == 0 or s[-1] != x:
results[1] = False
else:
s.pop()
if len(h) == 0 or h[0] != -x :
results[2] = False
else:
heapq.heappop(h)
if i == len(op)-1:
results_global.append(results)
printstructures(results_global)
if __name__ == "__main__":
main()
I was wondering if anyone can give me a push in the right direction and point out where my thinking is wrong or if I made a mistake somewhere I overlooked.
I had the same runtime-error problem for this question, I think it has something to do with python input/output EOFError. I couldn't figure the specific error out but I just put a try/except pass over my entire program and kattis accepted the solution.
import sys
try:
def solve(n):
stack = []
queue = []
priority_queue = []
type_ds = [True, True, True]
for i in range(n):
command, element = map(int, input().split())
if command == 1:
if type_ds[0] != False:
stack.append(element)
if type_ds[1] != False:
queue.append(element)
if type_ds[2] != False:
priority_queue.append(element)
elif command == 2:
if type_ds[0] != False:
if len(stack) == 0:
return "impossible"
if element != stack.pop():
type_ds[0] = False
stack.clear()
if type_ds[1] != False:
if len(queue) == 0:
return "impossible"
if element != queue.pop(0):
type_ds[1] = False
queue.clear()
if type_ds[2] != False:
if len(priority_queue) == 0:
return "impossible"
priority_queue.sort(reverse=True)
if element != priority_queue.pop(0):
type_ds[2] = False
priority_queue.clear()
if type_ds.count(True) > 1:
return "not sure"
elif type_ds.count(True) == 0:
return "impossible"
else:
if type_ds[0] == True:
return "stack"
elif type_ds[1] == True:
return "queue"
else:
return "priority queue"
for line in sys.stdin:
if line.strip() == "":
break
n = int(line.strip())
print(solve(n))
except:
pass
Are you sure you're breaking out of the while loop? Is it running correctly on your computer? In competitive programming, with time limits, it's normally not a good idea to use try/except statements, it's slowing down the script by a lot.

IndexError: String Index out of range for recursive function

So I am learning python and am trying to count the number of vowels in a sentence. I figured out how to do it both using the count() function and an iteration but now I am trying to do it using recursion. When I try the following method I get an error "IndexError: string index out of range". Here is my code.
sentence = input(": ")
def count_vowels_recursive(sentence):
total = 0
if sentence[0] == "a" or sentence[0] == "e" or sentence[0] == "i" or sentence[0] == "o" or sentence[0] == "u":
total = total + 1 + count_vowels_recursive(sentence[1:])
else:
total = total + count_vowels_recursive(sentence[1:])
return the_sum
print(count_vowels_recursive(sentence))
Here are my previous two solutions.
def count_vowels(sentence):
a = sentence.count("a")
b = sentence.count("e")
c = sentence.count("i")
d = sentence.count("o")
e = sentence.count("i")
return (a+b+c+d+e)
def count_vowels_iterative(sentence):
a_ = 0
e_ = 0
i_ = 0
o_ = 0
u_ = 0
for i in range(len(sentence)):
if "a" == sentence[i]:
a_ = a_ + 1
elif "e" == sentence[i]:
e_ = e_ + 1
elif "i" == sentence[i]:
i_ = i_ + 1
elif "o" == sentence[i]:
o_ = o_ + 1
elif "u" == sentence[i]:
u_ = u_ + 1
else:
continue
return (a_ + e_ + i_ + o_ + u_)
You have no base case. The function will keep recursing until sentence is empty, in which case your first if statement will cause that index error.
You should first of all check if sentence is empty, and if so return 0
You can shorten things up quite a bit:
def count_vowels_recursive(sentence):
# this base case is needed to stop the recursion
if not sentence:
return 0
# otherwise, sentence[0] will raise an exception for the empty string
return (sentence[0] in "aeiou") + count_vowels_recursive(sentence[1:])
# the boolean expression `sentence[0] in "aeiou"` is cast to an int for the addition
You can try this:
def count_vowels_recursive(s, count):
if not s:
return count
else:
new_count = count
if s[0] in ["a", "e", "i", "o", "u"]:
new_count += 1
return count_vowels_recursive(s[1:], new_count)

Loop stops even though only 1 of 2 variables is true

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.

Update Dictionary in python

I want to inset new key,value pair into a variable that was not previously defined
Here is what i want to do:
def drawboard(nextmove):
result = nextmove
pos = 1
print result
for i in range(7):
for j in range(7):
if (j == 0 or i % 2 == 0 or j % 2 == 0):
print '*',
if (i % 2 != 0 and j % 2 != 0):
print pos,
pos += 1
if (j == 6):
print '\n'
move = raw_input("Input you move(i.e. x,3[position, your symbol]: ")
if move == 'q':
exit()
calcres(move)
def calcres(move):
nextmove = dict([move.split(',')])
drawboard(nextmove)
drawboard({0: 0})
Inside drawboard function i want to concatenate nextmove with result, and save all the moves inside the result finally. I tried initializing result = {} but as expected that removes all items from result and re-initializes it resulting only one item inside that dictionary.
Use setdefault to initialize the result dictionary value to an empty list whenever the key is not present
def drawboard(nextmove):
result.setdefault(nextmove[0],[]).append(nextmove[1])
pos = 1
#print result
for i in range(7):
for j in range(7):
if (j == 0 or i % 2 == 0 or j % 2 == 0):
print '*',
if (i % 2 != 0 and j % 2 != 0):
print pos,
pos += 1
if (j == 6):
print '\n'
move = raw_input("Input you move(i.e. x,3[position, your symbol]: ")
if move == 'q':
exit()
calcres(move)
def calcres(move):
nextmove = move.split(',')
drawboard(nextmove)
result = {}
drawboard([0,0])

Categories