Appending a new line to file - python

I am wondering how to append a newline every time the list reaches the size of the checker board (8). Heres my code so far. It works but I want to put a newline every 8 characters.
saveFile=input("Please enter the name of the file you want to save in: ")
outputFile=open(saveFile,"w")
pieceList=[]
for row_index in range (self.SIZE):
for column_index in range(self.SIZE):
pieceRow=[]
char=" "
if self.grid[row_index][column_index]==Piece(Piece.WHITE):
char="w"
elif self.grid[row_index][column_index]==Piece(Piece.RED):
char="r"
pieceRow.append(char)
pieceList.append(pieceRow)
for item in pieceList:
for char in item:
outputFile.write("%s" %char)

Use
if row_index % 8 == 0:
# put newline

saveFile=input("Please enter the name of the file you want to save in: ")
outputFile=open(saveFile,"w")
pieceList=[]
characterCounter =0
for row_index in range (self.SIZE):
for column_index in range(self.SIZE):
pieceRow=[]
char=" "
if self.grid[row_index][column_index]==Piece(Piece.WHITE):
char="w"
elif self.grid[row_index][column_index]==Piece(Piece.RED):
char="r"
pieceRow.append(char)
characterCounter++
if characterCounter==8:
pieceRow.append("\n")
characterCounter=0
pieceList.append(pieceRow)
for item in pieceList:
for char in item:
outputFile.write("%s" %char)

cnt = 0
for item in pieceList:
for char in item:
outputFile.write("%s" %char)
cnt += 1
if cnt == 8:
outputFile.write("\n")
cnt = 0

Do you mean you want to append newline after each row?
Why not add
pieceRow.append("\n")
before
pieceList.append(pieceRow)

You could use enumerate,
For instance,
CONST_SIZE = 8
for index, item in enumerate(item_list):
output_file.write(item)
if index % 8 == 0: output_file.write('\n')
This will append a newline each time you've written 8 items to the file.

Related

How is my python code going out of bound?

I've been trying to encode a string (ex: aabbbacc) to something like a2b3a1c2
this is the code i've tried:
string_value = "aabbbacc"
temp_string = ""
for i in range(0, len(string_value)):
if i != len(string_value) or i > len(string_value):
temp_count = 1
while string_value[i] == string_value[i+1]:
temp_count += 1
i += 1
temp_string += string_value[i] + str(temp_count)
print(temp_string)
the problem is even though I've added an if condition to stop out of bounds from happening, I still get the error
Traceback (most recent call last):
File "C:run_length_encoding.py", line 6, in <module>
while string_value[i] == string_value[i+1]:
IndexError: string index out of range
I've also tried
string_value = "aabbbacc"
temp_string = ""
for i in range(0, len(string_value)):
count = 1
while string_value[i] == string_value[i+1]:
count += 1
i += 1
if i == len(string_value):
break
temp_string += string_value[i]+ str(count)
print(temp_string)
now, I know there might be a better way to solve this, but I'm trying to understand why I'm getting the out of bounds exception even though i have an if condition to prevent it, at what part of the logic am I going wrong please explain...
The problem is here:
for i in range(0, len(string_value)): # if i is the last index of the string
count = 1
while string_value[i] == string_value[i+1]: # i+1 is now out of bounds
The easiest way to avoid out-of-bounds is to not index the strings at all:
def encode(s):
if s == '': # handle empty string
return s
current = s[0] # start with first character (won't fail since we checked for empty)
count = 1
temp = ''
for c in s[1:]: # iterate through remaining characters (string slicing won't fail)
if current == c:
count += 1
else: # character changed, output count and reset current character and count
temp += f'{current}{count}'
current = c
count = 1
temp += f'{current}{count}' # output last count accumulated
return temp
print(encode('aabbbacc'))
print(encode(''))
print(encode('a'))
print(encode('abc'))
print(encode('abb'))
Output:
a2b3a1c2
a1
a1b1c1
a1b2
First this check is odd :
if i != len(string_value) or i > len(string_value):
Second, you check i but read value for i+1, and potentially next...
So my suggestion is to put the condition inside of your while.
And do not allow string_value[i] to be read after you have checked that i==len(string_value).
(I remind you that : "The break statement, like in C, breaks out of the innermost enclosing for or while loop.")
Iterate thru each char in the string then check if the next char is the same with current. If yes, then add one else add the count to temp string and reset the count to 1.
string_value = "aabbbacc"
temp_string = ""
count = 1
for i in range(len(string_value)-1):
if string_value[i] == string_value[i+1]:
count += 1
else:
temp_string += string_value[i]+ str(count)
count = 1
#add the last char count
temp_string += string_value[i+1]+ str(count)
print(temp_string)
Out: a2b3a1c2

Without using built-in functions, a function should reverse a string without changing the '$' position

I need a Python function which gives reversed string with the following conditions.
$ position should not change in the reversed string.
Should not use Python built-in functions.
Function should be an efficient one.
Example : 'pytho$n'
Result : 'nohty$p'
I have already tried with this code:
list = "$asdasdas"
list1 = []
position = ''
for index, i in enumerate(list):
if i == '$':
position = index
elif i != '$':
list1.append(i)
reverse = []
for index, j in enumerate( list1[::-1] ):
if index == position:
reverse.append( '$' )
reverse.append(j)
print reverse
Thanks in advance.
Recognise that it's a variation on the partitioning step of the Quicksort algorithm, using two pointers (array indices) thus:
data = list("foo$barbaz$$")
i, j = 0, len(data) - 1
while i < j:
while i < j and data[i] == "$": i += 1
while i < j and data[j] == "$": j -= 1
data[i], data[j] = data[j], data[i]
i, j = i + 1, j - 1
"".join(data)
'zab$raboof$$'
P.S. it's a travesty to write this in Python!
A Pythonic solution could look like this:
def merge(template, data):
for c in template:
yield c if c == "$" else next(data)
data = "foo$barbaz$$"
"".join(merge(data, reversed([c for c in data if c != "$"])))
'zab$raboof$$'
Wrote this without using any inbuilt functions. Hope it fulfils your criteria -
string = "zytho$n"
def reverse(string):
string_new = string[::-1]
i = 0
position = 0
position_new = 0
for char in string:
if char=="$":
position = i
break
else:
i = i + 1
j = 0
for char in string_new:
if char=="$":
position_new = i
break
else:
j = j + 1
final_string = string_new[:position_new]+string_new[position_new+1:position+1]+"$"+string_new[position+1:]
return(final_string)
string_new = reverse(string)
print(string_new)
The output of this is-
nohty$x
To explain the code to you, first I used [::-1], which is just taking the last position of the string and moving forward so as to reverse the string. Then I found the position of the $ in both the new and the old string. I found the position in the form of an array, in case you have more than one $ present. However, I took for granted that you have just one $ present, and so took the [0] index of the array. Next I stitched back the string using four things - The part of the new string upto the $ sign, the part of the new string from after the dollar sign to the position of the $ sign in the old string, then the $ sign and after that the rest of the new string.

extract value from loop within a loop

I have a list of lists and i am trying to loop through to create a new value in the second list based on two elements with the second list.
for line in input_list[1:]:
i = 0
for element in line:
if i == 13:
if line[7] > line[8]:
line[13] == 1
else:
line[13] == 0
i += 1
I am trying to set the value of line[13] based on the condition that line[7] is greater than line[8].
The code does not flag any errors, so syntactically it is correct, but when i print for the new list, it does not display any values (0 or 1) for line[13].
Any help would be much appreciated.
Thanks,
Ed
Use line[13] = 1 instead of line[13] == 1. == is for comparison.
It will not show the correct output because you haven't use assignment operator . use line[13] = 1 instead of line[13] == 1
Example :- list= [[1,2],[3,4,5]]
For this list -
for line in list[1:]:
i=0
for element in line:
if i==1:
if line[0]>line[1]:
line[1]=1
else:
line[1]=200
i=i+1
It will work
for line in input_list[1:]:
i = 0
for element in line:
if i == 13:
if line[7] > line[8]:
line[13] = 1
else:
line[13] = 0
i += 1
code updated

I have a list and I want to count the occurrence of items at a certain position in my list

I have a file which was transformed to a list. Now I want to count the occurrence of specific elements in a list at a specific position. Here is my code so far:
Inpu = open("I.txt","r")
entries = []
for line in Inpu:
line=line.lstrip()
if not line.startswith('#'):
row = line.split()
entries.append(row)
count0 = 0
count1 = 0
for item in entries:
try:
if item[3] == '1':
count1 += 1
if item[3] == '0':
count0 += 1
print item
except IndexError:
continue
This for loop statement works fine and gives me total of count1 and count0 in my file.
for line in Inpu:
line=line.lstrip
if not line.startwith('#'):
rows=line.split()
peptide_count.append(row)
for line in Inpu:
for i in line:
while i in line[0]=='1':
peptide_length+=1
if i in line[3] == '1':
count1= str(line[3]).count(1)
print (count1)
if i in line[3] == '0':
count0=str(item[3]).count(0)
print str(count0)
else:
if i in line[0]=='>':
break
print ("peptide_Lengths|1s|0s")
print(str(peptide_length) + "\t" + str(countones) + "\t" + str(countz))
This on the other hand is suppose to count the number of occurrences of zero's and ones's in line 3 when line[0] position starts with 1 and should break when it comes a cross '>' in line[0] in my file. But here is the out put I get which is obviously wrong:
peptide_Lengths|1s|0s
0 0 0
Is there anything I'm doing wrong or missing?

Tab Formatted Nested String to Nested List ~ Python

Hello guys, after managing to get some data by scraping with Beautiful Soup...
I want to format that data so as I could easily export it to CSV and JSON.
My Question here is how can one translate this:
Heading :
Subheading :
AnotherHeading :
AnotherSubheading :
Somedata
Heading :
Subheading :
AnotherHeading :
AnotherSubheading :
Somedata
Into this:
[
['Heading',['Subheading']],
['AnotherHeading',['AnotherSubheading',['Somedata']]],
['Heading',['Subheading']],
['AnotherHeading',['AnotherSubheading',['Somedata']]]
]
Indented for clarity
Any rescue attempt would be appreciated by a warm thank you!
So far with help we got:
def parse(data):
stack = [[]]
levels = [0]
current = stack[0]
for line in data.splitlines():
indent = len(line)-len(line.lstrip())
if indent > levels[-1]:
levels.append(indent)
stack.append([])
current.append(stack[-1])
current = stack[-1]
elif indent < levels[-1]:
stack.pop()
current = stack[-1]
levels.pop()
current.append(line.strip().rstrip(':'))
return stack
The problem with that code is that it returns...
[
'Heading ',
['Subheading '],
'AnotherHeading ',
['AnotherSubheading ', ['Somedata'], 'Heading ', 'Subheading '], 'AnotherHeading ',
['AnotherSubheading ', ['Somedata']]
]
Here is a repl:
https://repl.it/yvM/1
Thank you both kirbyfan64sos and SuperBiasedMan
def parse(data):
currentTab = 0
currentList = []
result = [currentList]
i = 0
tabCount = 0
for line in data.splitlines():
tabCount = len(line)-len(line.lstrip())
line = line.strip().rstrip(' :')
if tabCount == currentTab:
currentList.append(line)
elif tabCount > currentTab:
newList = [line]
currentList.append(newList)
currentList = newList
elif tabCount == 0:
currentList = [line]
result.append(currentList)
elif tabCount == 1:
currentList = [line]
result[-1].append(currentList)
currentTab = tabCount
tabCount = tabCount + 1
i = i + 1
print(result)
Well first you want to clear out unnecessary whitespace, so you make a list of all the lines that contain something more than whitespace and set up all the defaults that you start from for the main loop.
teststring = [line for line in teststring.split('\n') if line.strip()]
currentTab = 0
currentList = []
result = [currentList]
This method replies on the mutability of lists, so setting currentList as an empty list and then setting result to [currentList] is an important step, since we can now append to currentList.
for line in teststring:
i, tabCount = 0, 0
while line[i] == ' ':
tabCount += 1
i += 1
tabCount /= 8
This is the best way I could think of to check for tab characters at the start of each line. Also, yes you'll notice I actually checked for spaces, not tabs. Tabs just 100% didn't work, I think it was because I was using repl.it since I don't have Python 3 installed. It works perfectly fine on Python 2.7 but I wont put code I haven't verified works. I can edit this if you confirm that using \t and removing tabCount /= 8 produces the desired results.
Now, check how indented the line is. If it's the same as our currentTab value, then just append to the currentList.
if tabCount == currentTab:
currentList.append(line.strip())
If it's higher, that means we've gone to a deeper list level. We need a new list nested in currentList.
elif tabCount > currentTab:
newList = [line.strip()]
currentList.append(newList)
currentList = newList
Going backwards is trickier, since the data only contains 3 nesting levels I opted to hardcode what to do with the values 0 and 1 (2 should always result in one of the above blocks). If there are no tabs, we can append a new list to result.
elif tabCount == 0:
currentList = [line.strip()]
result.append(currentList)
It's mostly the same for a one tab deep heading, except that you should append to result[-1], as that's the last main heading to nest into.
elif tabCount == 1:
currentList = [line.strip()]
result[-1].append(currentList)
Lastly, make sure currentTab is updated to what our current tabCount is so the next iteration behaves properly.
currentTab = tabCount
Something like:
def parse(data):
stack = [[]]
levels = [0]
current = stack[0]
for line in data.splitlines():
indent = len(line)-len(line.lstrip())
if indent > levels[-1]:
levels.append(indent)
stack.append([])
current.append(stack[-1])
current = stack[-1]
elif indent < levels[-1]:
stack.pop()
current = stack[-1]
levels.pop()
current.append(line.strip().rstrip(':'))
return stack[0]
Your format looks a lot like YAML, though; you may want to look into PyYAML.

Categories

Resources