Python printing before/after different lines - python

I have created some code long ago which helps to create a table in BBcode used in forums.
counter = 0
counter2 = 0
while True:
UserInput = input("")
if counter2 == 0:
print ("[tr]")
print ("[td][center]Label\n" + "[img]" + str(UserInput) + "[/img][/center][/td]")
counter += 1
counter2 += 1
if counter % 5 == 0:
print ("[/tr]")
So if i input Image1.jpg ~ Image7.jpg on seperate lines, the output is as shown below
> [tr]
> [td][center]Label[img]Image1.jpg[/img][/center][/td]
> [td][center]Label[img]Image2.jpg[/img][/center][/td]
> [td][center]Label[img]Image3.jpg[/img][/center][/td]
> [td][center]Label[img]Image4.jpg[/img][/center][/td]
> [td][center]Label[img]Image5.jpg[/img][/center][/td]
> [/tr]
> [td][center]Label[img]Image6.jpg[/img][/center][/td]
> [td][center]Label[img]Image7.jpg[/img][/center][/td]
Currently, the code only inserts [/tr] at the end of ever 5 images.How does one make it so that [/tr] is also printed at the end of output no matter how many jpgs are entered?
How can I print [tr] at the start and join it with the line below, and then not print again until a [/tr] has been printed?
Apologies for my crap English & explanation skills.
(Current progress)
counter = 0
while True:
UserInput = input("")
if counter == 0 or counter % 5 == 0:
print("[tr]", end = "")
print ("[td][center]Label\n" + "[img]" + str(UserInput) + "[/img][/center][/td]")
counter += 1
if counter % 5 == 0:
print("[/tr]")

After reading what you wrote 5 times I believe what you want is:
print("[tr]")
while True:
counter = 0
UserInput = input("")
if UserInput == "exit":
exit(0)
print("[tr]", end = "")
while (counter !=5):
print ("[td][center]Label\n" + "[img]" + str(UserInput) + "[/img][/center][/td]")
counter += 1
print ("[/tr]")
print("[/tr]")
So what happens here is you print [tr] in the same line as the first print from the inside while as you wanted. the [/tr] is in a new line but you can put it in the same by adding end = "" to the second print as well.

Separate the functions. Get the list of images, then process it:
def bbcode(images):
for i in range(0,len(images),5):
print('[tr]')
for image in images[i:i+5]:
print(f'[td][center]Label[img]{image}[/img][/center][/td]')
print('[/tr]')
def get_images():
images = []
while True:
image = input('Image? ')
if not image: break
images.append(image)
return images
images = get_images()
bbcode(images)
You can do it as one long script, but it isn't as clear:
count = 0
while True:
image = input('Image? ')
if not image:
break
count = (count + 1) % 5
if count == 1:
print('[tr]')
print(f'[td][center]Label[img]{image}[/img][/center][/td]')
if count == 0:
print('[/tr]')
if count != 0:
print('[/tr]')

Below is the result with some commentary. To update for your specifications, just set the max_item_blocks variable to whatever you want.
### your main body element with {} to pass a number
element = '[td][center]Label[img]Image{}.jpg[/img][/center][/td]'
### The number of "blocks" you want to print.
max_item_blocks = 3
### Define a start value of 1
start = 1
### Our simple loop with join() function
while max_item_blocks > 0:
### End value is start + 5
end = start + 5
print('[tr]\n' + '\n'.join([element.format(i) for i in range(start, end)]) + '\n[\\tr]')
### Start takes ending value
start = end
### Ending value is now start + 5
end = start + 5
### Reduce our block counts by 1
max_item_blocks -= 1
Output for 3 blocks:
[tr]
[td][center]Label[img]Image1.jpg[/img][/center][/td]
[td][center]Label[img]Image2.jpg[/img][/center][/td]
[td][center]Label[img]Image3.jpg[/img][/center][/td]
[td][center]Label[img]Image4.jpg[/img][/center][/td]
[td][center]Label[img]Image5.jpg[/img][/center][/td]
[\tr]
[tr]
[td][center]Label[img]Image6.jpg[/img][/center][/td]
[td][center]Label[img]Image7.jpg[/img][/center][/td]
[td][center]Label[img]Image8.jpg[/img][/center][/td]
[td][center]Label[img]Image9.jpg[/img][/center][/td]
[td][center]Label[img]Image10.jpg[/img][/center][/td]
[\tr]
[tr]
[td][center]Label[img]Image11.jpg[/img][/center][/td]
[td][center]Label[img]Image12.jpg[/img][/center][/td]
[td][center]Label[img]Image13.jpg[/img][/center][/td]
[td][center]Label[img]Image14.jpg[/img][/center][/td]
[td][center]Label[img]Image15.jpg[/img][/center][/td]
[\tr]

Related

Print a changing variable in a for loop using one line in the ipython console

So im really not sure if this is possible but im trying to create a progress bar for my code in python but for each iteation i gt a new print line but what i want is the console to utilise the first statement...
progress = []
noDots = 50
noItems =601
if noItems >= noDots:
batch = int(noItems/noDots)
else:
noDots = noItems
batch = 1
for i in range(noDots):
progress.insert(0, '.')
for i in range(0,noItems,batch):
val = int(i/batch)
perc = round(((i/noItems)*100))
print(val)
if val ==0:
val == 0
else:
val -= 1
if progress[val] == '.':
progress[val] = '>'
if val == 0:
continue
else:
progress[val - 1] = '='
print(f'[{"".join(progress)}] {perc}%')
The output is as follows...
If you use sys.stdout you should be able to do it
# To see how far we're in the progress
string = '-'
for i in range(x):
sys.stdout.write('\r' + '(' + string + ' '*(max_len - len(string) + ')')
sys.stdout.flush()
string += '-'
It's important to have the '\r' character

Annotating adjacent values in a list

It's supposed to be a roll of dice (random) then adjacent values (runs) are supposed to be in ( ). One challenge is using the current - 1 with the 0 index (think I got that resolved by using range(len(dieRun) -1). But another challenge is using 'current + 1' as it tends to 'out of range' errors.
One thought I have is to maybe build a function to compare the values for adjacents? Then use whatever return I get from that to reference a variable, then use that variable in a formatted Print of the dieRun? But, I don't see how that would be better as then I'd still have to figure out how to place that variable as a "(" or ")" with the print(dieRun) list.
Still a newb.
def main():
from random import randint
counter = 0
inRun = 0
dieRun = []
while counter < 20:
roll = randint(0,6)
dieRun.append(roll)
counter = counter +1
index = 0
counter = 0
value = 0
inRun == False
print(dieRun) # just to see what I'm working with
while counter < len(dieRun):
for i in range(0, len(dieRun)-1):
if dieRun[i] != dieRun[i-1]:
print(")" , end= "")
inRun = False
counter = counter + 1
if dieRun[i] == dieRun[i+1]:
inRun = True
print("(")
counter = counter + 1
print(dieRun[i])
if inRun:
print("(")
if inRun :
print(")", end="")
main()
if you want the output like: 1(3 3) 4 5 (6 6 6) 2 1 3 (2 2) 1 (4 4) 5 6 1 2
from random import randint
dieRun = []
for i in range(20):
roll = randint(0,6)
dieRun.append(roll)
inRun = False
print(dieRun)
for i, n in enumerate(dieRun):
if i < len(dieRun)-1:
if not inRun:
if n == dieRun[i+1]:
print('(', n,' ', end='')
inRun = True
else:
print(n,' ', end='')
else:
if n != dieRun[i+1]:
print(n, ')',' ', end='')
inRun = False
else:
print(n,' ', end='')
else:
if dieRun[i-1] == n:
print(n, ')')
else:
print(n)
just a thought, hope it help.
Just a quick fix, I have commented in the code.
For the inline print, you have provided the solution 'print(")" , end= "")', but I don't know why you didn't make it for every print().
if dieRun[i] != dieRun[i-1]: # will check the first number with last number
dieRun[0] != dieRun[-1]: # [-1] is the last item in the list
if dieRun[i] == dieRun[i+1]: # will index out of length
dieRun[len(..)-1] != dieRun[len(..)]: # [len(..)] wil be out of range
Since the head and tail of the list will always cause problem, I just chopped them off from the for loop, and do it manually.
There must be some cleaner solution:
from random import randint
counter = 0
inRun = 0
dieRun = []
while counter < 20:
roll = randint(0,6)
dieRun.append(roll)
counter = counter +1
index = 0
counter = 0
value = 0
inRun == False
print(dieRun)
# while counter < len(dieRun): # while loop is redundant with the for loop
print('(', dieRun[0],' ', end='') # print the first number manually
for i in range(1, len(dieRun)-1):
if dieRun[i] != dieRun[i-1]:
print(")(" , end= "") # change ")" to ")("
inRun = False
counter = counter + 1
"""
these are redundant, just like if True, don't need elif not True
# if dieRun[i] == dieRun[i+1]:
# inRun == True
# print("(", end='')
# counter = counter + 1
"""
print(dieRun[i],' ', end='')
print(dieRun[-1],')', end='') # print the last number manually

Is there a way to print one string and prevent it from reprinting in a random string generator?

I've made a program that can print out a random row of characters for a dungeon-crawler like game and I'm wondering if I can make it to have the # symbol print once and only once.
I have tried making it check the list of previously printed strings and making sure that if it has been printed it won't print again but that doesn't seem to be working and I'm kinda new to this. Any suggestions?
import random
import time
randomnumber = random.randint(6,16)
block = []
printed = []
health = 10
blocks = "\x1b[1;37;48m#"
x_axis = 1
y_axis = 1
randumplace = random.randint(0, len(block))
multiplier = random.randrange(6,35)
def build(blocks):
for i in range (multiplier):
block.append(blocks)
i = random.randrange(1,75)
if i == 4:
blocks = "\x1b[1;31;48mM"
elif i == 15:
blocks = "\x1b[1;36;48m~"
elif i == 25:
blocks = "\x1b[1;36;48m~"
elif i == 22:
blocks = "\x1b[1;33;48m$"
elif i == 1:
blocks = "\x1b[1;37;48m#"
elif i == 10 and "#" not in printed:
blocks = "#"
else:
blocks = "\x1b[1;37;48m."
fip = build(blocks)
counter = 1
print("# "+"# # # # # #" + " #" * (multiplier - 6))
while counter != randomnumber:
printed.append(block)
del block[:]
build(blocks)
print (*block)
counter += 1
print ("" + "# " * (multiplier +1))
It should print out 5 - 15 lines of strings like "# . . . . M . . $ . . # . . ."
but it instead prints multiple # symbols like
"# . . . . # M . . . # . . # . . ."
I also want to make sure that other lines don't also print the # symbol, and that's the reason for the "printed" list.
A much easier approach is to create a matrix in memory, e.g.
maze = [[' '] * random_width for i in range(random_height)]
then you fill the maze as you like and only when it's complete you print it.
First of all, collapse your choice of blocks into a simple look-up table:
rand_limit = 75
block = ["\x1b[1;37;48m."] * rand_limit
block[01] = "\x1b[1;37;48m#"
block[04] = "\x1b[1;31;48mM"
block[15] = "\x1b[1;36;48m~"
block[22] = "\x1b[1;33;48m$"
block[25] = "\x1b[1;36;48m~"
Now you can do your entire maze as a nested list comprehension, substituting the block symbols for the random numbers:
maze_rows = random.randrange(6, 35)
maze_cols = random.randrange(5, 16)
maze = [ [block[random.randrange(1, rand_limit)]
for col in range(maze_cols)]
for row in range(maze_rows) ]
Finally, pick a random row and column for your unique symbol:
maze[random.randrange(maze_rows][random.randrange(maze_cols]] = '#'
If you don't want to overwrite an existing symbol, then loop until you hit a blank spot.
I just moved the printed.append() function up into the build function.
Try this:
import random
import time
randomnumber = random.randint(6,16)
block = []
printed = []
health = 10
blocks = "\x1b[1;37;48m#"
x_axis = 1
y_axis = 1
randumplace = random.randint(0, len(block))
multiplier = random.randrange(6,35)
def build(blocks):
for i in range (multiplier):
block.append(blocks)
i = random.randrange(1,75)
if i == 4:
blocks = "\x1b[1;31;48mM"
elif i == 15:
blocks = "\x1b[1;36;48m~"
elif i == 25:
blocks = "\x1b[1;36;48m~"
elif i == 22:
blocks = "\x1b[1;33;48m$"
elif i == 1:
blocks = "\x1b[1;37;48m#"
elif i == 10 and "#" not in printed:
blocks = "#"
printed.append("#")
else:
blocks = "\x1b[1;37;48m."
fip = build(blocks)
counter = 1
print("# "+"# # # # # #" + " #" * (multiplier - 6))
while counter != randomnumber:
del block[:]
build(blocks)
print (*block)
counter += 1
print ("" + "# " * (multiplier +1))

How do I run a binary search for words that start with a certain letter?

I am asked to binary search a list of names and if these names start with a particular letter, for example A, then I am to print that name.
I can complete this task by doing much more simple code such as
for i in list:
if i[0] == "A":
print(i)
but instead I am asked to use a binary search and I'm struggling to understand the process behind it. We are given base code which can output the position a given string. My problem is not knowing what to edit so that I can achieve the desired outcome
name_list = ["Adolphus of Helborne", "Aldric Foxe", "Amanita Maleficant", "Aphra the Vicious", "Arachne the Gruesome", "Astarte Hellebore", "Brutus the Gruesome", "Cain of Avernus"]
def bin_search(list, item):
low_b = 0
up_b = len(list) - 1
found = False
while low_b <= up_b and found == False:
midPos = ((low_b + up_b) // 2)
if list[midPos] < item:
low_b = midPos + 1
elif list[midPos] > item:
up_b = midPos - 1
else:
found = True
if found:
print("The name is at positon " + str(midPos))
return midPos
else:
print("The name was not in the list.")
Desired outcome
bin_search(name_list,"A")
Prints all the names starting with A (Adolphus of HelBorne, Aldric Foxe .... etc)
EDIT:
I was just doing some guess and check and found out how to do it. This is the solution code
def bin_search(list, item):
low_b = 0
up_b = len(list) - 1
true_list = []
count = 100
while low_b <= up_b and count > 0:
midPos = ((low_b + up_b) // 2)
if list[midPos][0] == item:
true_list.append(list[midPos])
list.remove(list[midPos])
count -= 1
elif list[midPos] < item:
low_b = midPos + 1
count -= 1
else:
up_b = midPos - 1
count -= 1
print(true_list)
Not too sure if this is what you want as it seems inefficient... as you mention it seems a lot more intuitive to just iterate over the entire list but using binary search i found here i have:
def binary_search(seq, t):
min = 0
max = len(seq) - 1
while True:
if max < min:
return -1
m = (min + max) // 2
if seq[m][0] < t:
min = m + 1
elif seq[m][0] > t:
max = m - 1
else:
return m
index=0
while True:
index=binary_search(name_list,"A")
if index!=-1:
print(name_list[index])
else:
break
del name_list[index]
Output i get:
Aphra the Vicious
Arachne the Gruesome
Amanita Maleficant
Astarte Hellebore
Aldric Foxe
Adolphus of Helborne
You just need to found one item starting with the letter, then you need to identify the range. This approach should be fast and memory efficient.
def binary_search(list,item):
low_b = 0
up_b = len(list) - 1
found = False
midPos = ((low_b + up_b) // 2)
if list[low_b][0]==item:
midPos=low_b
found=True
elif list[up_b][0]==item:
midPos = up_b
found=True
while True:
if found:
break;
if list[low_b][0]>item:
break
if list[up_b][0]<item:
break
if up_b<low_b:
break;
midPos = ((low_b + up_b) // 2)
if list[midPos][0] < item:
low_b = midPos + 1
elif list[midPos] > item:
up_b = midPos - 1
else:
found = True
break
if found:
while True:
if midPos>0:
if list[midPos][0]==item:
midPos=midPos-1
continue
break;
while True:
if midPos<len(list):
if list[midPos][0]==item:
print list[midPos]
midPos=midPos+1
continue
break
else:
print("The name was not in the list.")
the output is
>>> binary_search(name_list,"A")
Adolphus of Helborne
Aldric Foxe
Amanita Maleficant
Aphra the Vicious
Arachne the Gruesome
Astarte Hellebore

My state machine in Python runs into infinite loop

I am new to python. My code runs into infinite loop, keeps adding & printing numberCycles. My logic in C++ works fine.
Would you please help to identify why?
The first line of input is the number of simulations.
The next line is the number of minutes for a single reproductive cycle.
The next line is the number of rows (x), followed by a single space, and followed by number of columns (y).
The next group of y lines will have x number of characters, with a single period (.) representing a blank space and a single capitol B representing a starting Bunny tries to reproduce to up, right, down, left direction. If there is a existing bunny, then it goes to sleep.
Input.txt
2 # 2 simulations
5 # 5 minutes/cycle
3 3 # 3*3 map
...
.B.
...
1
4 4
B.BB
..B.
...
B.B
Spot.py
#!/usr/bin/env python
class Spot(object):
isBunny = bool()
nextCycle = 0
UP = 0
RIGHT = 1
DOWN = 2
LEFT = 3
SLEEP = 4
def __init__(self, newIsBunny):
self.isBunny = newIsBunny
self.nextCycle = self.UP
def setNextCycle(self):
if (self.nextCycle != self.SLEEP):
self.nextCycle += 1
def getNextCycle(self):
return self.nextCycle
def getIsBunny(self):
return self.isBunny
def makeBunny(self):
if not self.isBunny:
self.nextCycle = self.UP
self.isBunny = True
Bunny.py
#!/usr/bin/env python
from Spot import Spot
import os
class Bunny(object):
#classmethod
def main(cls, args):
with open(os.path.expanduser('~/Desktop/input.txt')) as f:
numSims = int(f.readline())
myMap = []
print numSims
minPerCycle= int(f.readline())
print minPerCycle
for k in xrange(numSims):
xyLine= f.readline()
row = int(xyLine.split()[0])
col = int(xyLine.split()[1])
print row,col
for i in range(0,row):
myLine = f.readline()
myMap.append([])
for j in range(0,col):
myMap[i].append(Spot(myLine[j] == 'B'))
numCycles = 1
if cls.isFilled(row,col,myMap):
numCycles = 0
while not cls.isFilled(row,col,myMap):
numCycles += 1
print numCycles
for m in range(0,row):
for n in range(0,col):
if myMap[m][n].getIsBunny():
if myMap[m][n].getNextCycle() == Spot.UP:
if m>0:
myMap[m-1][n].makeBunny()
break
elif myMap[m][n].getNextCycle() == Spot.RIGHT:
if n<col-1:
myMap[m][n+1].makeBunny()
break
elif myMap[m][n].getNextCycle() == Spot.DOWN:
if m<row-1:
myMap[m+ 1][n].makeBunny()
break
elif myMap[m][n].getNextCycle() == Spot.SLEEP:
if n>0:
myMap[m][n- 1].makeBunny()
break
myMap[m][n].setNextCycle()
time = numCycles * minPerCycle
print "It took " , time , " minutes for the bunnies to take over the world!\n"
del myMap[:]
f.close()
#classmethod
def isFilled(cls,row,col,myMap):
for a in range(0,row):
for b in range(0,col):
if not myMap[a][b].getIsBunny():
return False
return True
if __name__ == '__main__':
import sys
Bunny.main(sys.argv)
It never goes to the left. Also, you set a break for the inner loop, so, myMap[m][n].setNextCycle() is never called. I just saw your C++ code and you translated it to Python with errors (using Spot.SLEEP instead of Spot.LEFT).
The break statement makes sense in C++ because you want to break the switch. Here, you are using if..else.
It should be something like:
while not cls.isFilled(row, col, myMap):
numCycles += 1
print numCycles
for m in range(0,row):
for n in range(0,col):
if myMap[m][n].getIsBunny():
if myMap[m][n].getNextCycle() == Spot.UP:
if m>0:
myMap[m-1][n].makeBunny()
elif myMap[m][n].getNextCycle() == Spot.RIGHT:
if n<col-1:
myMap[m][n+1].makeBunny()
elif myMap[m][n].getNextCycle() == Spot.DOWN:
if m<row-1:
myMap[m+ 1][n].makeBunny()
elif myMap[m][n].getNextCycle() == Spot.LEFT:
if n>0:
myMap[m][n-1].makeBunny()
myMap[m][n].setNextCycle()

Categories

Resources