I'd like to create menu boxes in Python with the following ascii characteres:
ASCII code 200 = ╚ ( Box drawing character double line lower left corner )
ASCII code 201 = ╔ ( Box drawing character double line upper left corner )
ASCII code 202 = ╩ ( Box drawing character double line horizontal and up )
ASCII code 203 = ╦ ( Box drawing character double line horizontal down )
ASCII code 204 = ╠ ( Box drawing character double line vertical and right )
ASCII code 205 = ═ ( Box drawing character double horizontal line )
ASCII code 206 = ╬ ( Box drawing character double line horizontal vertical )
However it seems that these are not supported. When I use chr() the system prints something totally different.
Do you have any advise on how to print the mentioned characters using Python 3?
Thank you.
It seems to work with string literals:
>>> symbs = [u'\u255a', u'\u2554', u'\u2569', u'\u2566', u'\u2560', u'\u2550', u'\u256c']
>>> for sym in symbs:
... print(sym)
...
╚
╔
╩
╦
╠
═
╬
This appears to work on all platforms I've tried it on, Windows 7, Mac OS , Linux, etc.
Codes gotten from http://svn.python.org/projects/stackless/trunk/Lib/encodings/cp720.py
Hope this helps.
Follow-up thanks to Dave Edwards ...
class TableBorder:
def __init__ (self, top_left, top_split, top_right,
mid_left, mid_split, mid_right,
low_left, low_split, low_right,
horizontal, vertical):
self.top_left = top_left
self.top_split = top_split
self.top_right = top_right
self.mid_left = mid_left
self.mid_split = mid_split
self.mid_right = mid_right
self.low_left = low_left
self.low_split = low_split
self.low_right = low_right
self.horizontal = horizontal
self.vertical = vertical
Borders0 = TableBorder ('+', '+', '+', '+', '+', '+', '+', '+', '+', '-', '|')
Borders1 = TableBorder (u'\u250c',u'\u252C',u'\u2510',u'\u251C',u'\u253C',u'\u2524',u'\u2514',u'\u2534',u'\u2518',u'\u2500',u'\u2502')
Borders2 = TableBorder (u'\u2554',u'\u2566',u'\u2557',u'\u2560',u'\u256C',u'\u2563',u'\u255a',u'\u2569',u'\u255d',u'\u2550',u'\u2551')
def draw_box (width, height, box):
span = width-2
line = box.horizontal * (span)
print (box.top_left + line + box.top_right)
body = box.vertical + (' '*span) + box.vertical
for _ in range (height-1):
print (body)
print (box.low_left + line + box.low_right)
draw_box (20, 10, Borders1)
Related
In order to make further transformation solely over the text parts, I want to split a latex file regarding the nature of the environment : for example, if I have :
latex_text = """A latex example
$$ \int = 0$$
with different
\[\sum \]
\[\sum \]
math delimiters $\\cos(x)$.
"""
I would like to obtain something like this :
["A latex example","$$ \int = 0$$","with different","\[\sum \]", "\[\sum \]","math delimiters","$\\cos(x)$","."]
With re.split(r'([\\][[]|[\\][]]|[$][$]|[$])',latex_text), I have
['A latex example\n', '$$', ' \\int = 0', '$$', '\nwith different\n', '\\[', '\\sum ', '\\]', ' \n', '\\[', '\\sum ', '\\]', '\nmath delimiters ', '$', '\\cos(x)', '$', '.\n']
Which is a start, but I need to re-attach the latex math delimiters : I was wondering if it was possible to let them in from the start ?
I finally did it with the code :
res_prem = re.split(r'([\\][[]|[\\][]]|[$][$]|[$])',latex_text)
delim = {r'\[',r'$$',r'$'}
res = []
i = 0
while i < len(res_prem):
u = res_prem[i]
if u in delim:
compact = res_prem[i] + res_prem[i+1] + res_prem[i+2]
res.append(compact)
i = i + 3
else:
res.append(u)
i += 1
Not sure that it is really pythonic, so any improvement is welcome !
How can I tab between two variables in this print statement? The code is straight from a textbook example but it's not working on the final print statement. It just prints out '\t' instead of tabbing. Is this a data type issue?
The code below uses loop to display table showing 1-10 & their squares
print('Number \t Square')
print('--------------')
for number in range (1,11):
square=number**2
print(number, '\t', square)
Formatting (indenting) is essential in Python. The code works fine when you format it like this:
print('Number \t Square')
print('--------------')
for number in range (1,11):
square=number**2
print(number, '\t', square)
This is what you need to do:
left_width = len("Number")
right_width = len("Square")
print('Number \t Square')
print('--------------')
for number in range(1, 11):
square = number ** 2
left_text = str(number).ljust(left_width)
right_text = str(square).rjust(right_width)
print(f"{left_text} \t {right_text}")
Srings in python have 'ljust', 'rjust' & 'center' methods that come into handy for similar occasions.
Sorry english not first language:
I started python today in school and I can't figure this out, I am also specified to use procedural programming, so I can't call in classes like .textwrap or .format.
Here's the code:
x_max = 0
y_max = 0
menu = ["1. Somma", "2. Sottrazione", "3. Moltiplicazione", "4. Divisione", "5. Exit"]
y_max = len(menu)
for x in range(len(menu)):
p = len(menu[x])
if (x_max < p):
x_max = p
x_tabella = x_max
print("╔", end = '')
for x in range (x_tabella+4):
print ("═", end = '')
print ("╗")
for x in range(y_max):
print ("║ ", end = '')
print (menu[x], end = '') != x_max
print (" ║")
print("╚", end = '')
for x in range (x_tabella+4):
print ("═", end = '')
print ("╝")
The objective is to put a border, like a menu around the options, with the options centered in the borders. The problem is I don't know how to center it properly, cause the left side looks fine, but the right side is all off center. It's supposed to be a code where whatever option you put into the menu it extends and adapts the border.
This is how it ends up currently
I would really appreciate some help, thanks.
So I don't really understand your intention with this line:
print (menu[x], end = '') != x_max
But change it to:
print(menu[x] + ' '*(x_max-len(menu[x])), end = '')
And you should get the expected output.
Within my program I have a Popup object that upon being created, draws a message to the screen, pauses, and then removes it. This works absolutely fine most of the time, including when messages are chained together one after the other. However, if at any point the game window comes out of focus for any reason (it is minimized or you click on another window), then after one or two chained popups, the screen will freeze and not show any subsequent ones, becoming responsive again after the last popup would have disappeared. This appears to occur just before the popup disappears, as the one it gets stuck on remains visible for the duration of the freeze.
I have no idea if this is a problem with Python or Pygame, but I'm hoping it's something I've done so it can be fixed. Does anyone have any idea what is happening?
class Popup():
def __init__(self,surface,font,colour,thickness,text,textcolour,duration,align="center",x=None,y=None): #Position can be specified, but will default to centre of screen.
self.surface = surface
self.font = font
self.colour = colour
self.x = x
self.y = y
self.thickness = thickness
self.text = text
self.textcolour = textcolour
self.duration = duration
self.align = align
self.appear()
sleep(self.duration) #I want to thread this if I can. For now, it pauses the entire program, so don't use long durations!
self.disappear()
def appear(self):
screenBorder = pygame.Rect(0,0,self.surface.get_width()-10,50) #Limits text width to slightly smaller than screen.
message = multiLineText(None,self.font,self.text,self.textcolour,screenBorder,self.align)
POPUPSURF = pygame.Surface((message.get_width()+(self.thickness*2),message.get_height()+(self.thickness*2))).convert_alpha() #New surface size of message plus border.
POPUPSURF.fill(self.colour)
POPUPSURF.blit(message,(self.thickness,self.thickness)) #Add the text.
if self.thickness > 0:
alphas = []
increment = int(255/self.thickness)
for i in range(self.thickness):
alphas.append(increment*(i+1))
for alpha in alphas:
num = alphas.index(alpha)
thisL = POPUPSURF.get_width() - (2*num)
thisH = POPUPSURF.get_height() - (2*num)
R,G,B = self.colour
pygame.draw.rect(POPUPSURF,(R,G,B,alpha),(num,num,thisL,thisH),1) #Draw border.
if self.x == None:
self.x = (self.surface.get_width()/2) - (POPUPSURF.get_width()/2)
if self.y == None:
self.y = (self.surface.get_height()/2) - (POPUPSURF.get_height()/2)
self.BACKUPSURF = pygame.Surface((POPUPSURF.get_width(),POPUPSURF.get_height()))
self.BACKUPSURF.blit(self.surface,(0,0),(self.x,self.y,POPUPSURF.get_width(),POPUPSURF.get_height())) #Takes a copy of what it looks like without popup. This can be restored in disappear().
self.surface.blit(POPUPSURF,(self.x,self.y))
pygame.display.update()
def disappear(self):
self.surface.blit(self.BACKUPSURF,(self.x,self.y))
pygame.display.update()
sleep(0.1)
Example of usage:
expGainPopup = Popup(DISPLAYSURF,font,DARKRED,10,"You have gained %d EXP!" %gain,WHITE,DURATION) #Inform of gain.
if player["Level"] < 15: #If not max level (would cause out-of-bounds error on array)
progressPopup = Popup(DISPLAYSURF,font,DARKRED,10,"You now have %d EXP out of %d to level up." %(player["EXP"], levels[player["Level"]]),WHITE,DURATION) #Inform of progress.
If anyone wants to test the code, they will also need the MultiLineText function:
def multiLineText(background,font,text,colour,boundary=None,align="left",returnNum=False): #NB the boundary ONLY cares about width/length. It will not limit the height of returned surface objects.
if type(boundary) == pygame.Rect: #If a valid boundary is passed
testSection = ""
testResult = ""
for word in findall(r'\S+|\n',text): #Borrowed this from my text compressor program. Splits all words and newlines, as \S+ finds a non-whitespace character and all similar characters following it. \n will match all newlines, treating them as words. | is just the 'or' operator. r makes it a raw string so Python doesn't get confused with all the formatting symbols.
testSection += " "+word #Remember to add spaces back in!
if word == "\n":
testResult += testSection #Skip check and auto-newline if it is a newline
testSection = ""
elif font.size(testSection)[0] > boundary.width: #If has exceeded one line length
testSection = testSection[:-len(word)-1] #Remove the word, -1 also removes the space before the word.
testResult += testSection+"\n" #Add string with line break to the result.
testSection = " "+word #Restart testSection with word that did not fit, ready for new line.
testResult += testSection #Add the last section that never reached the max length to the output so it doesn't get lost.
lines = testResult.split("\n")
for i in range(len(lines)):
lines[i] = lines[i][1:] #Removes the first character, an unwanted space.
else: #If just working off existing \n in the text
lines = text.split("\n")
lengths = []
for line in lines:
lengths.append(font.size(line)[0])
length = max(lengths) #Length is set to the length of the longest individual line.
totalHeight = 0
for line in lines:
totalHeight += font.size(line)[1]
TEXTSURF = pygame.Surface((length,totalHeight)).convert_alpha()
if background != None: #Fill the background with colour or transparency.
TEXTSURF.fill(background)
else:
TEXTSURF.fill((0,0,0,0))
for i in range(len(lines)):
lines[i] += str(i) #Add a unique identifier onto every line. This way if two or more lines are the same, index(line) will not return the wrong value, resulting in repeated lines not appearing.
for line in lines:
dudChars = len(str(lines.index(line))) #The number of characters in the index of this line within lines, and therefore the character length of the unique identifier we want to remove.
renderedLine = font.render(line[:-dudChars],True,colour) #Render the line without identifier.
if align == "left":
xpos = 0
elif align == "center":
xpos = (length/2) - (renderedLine.get_width()/2)
elif align == "right":
xpos = length - renderedLine.get_width()
ypos = int((lines.index(line)) * (totalHeight/len(lines))) #Find the appropriate vertical space
TEXTSURF.blit(renderedLine,(xpos,ypos)) #Add to the multiline surface.
if returnNum == False:
return TEXTSURF
else:
return TEXTSURF, len(lines) #Return the number of lines used as well, if it was asked for.
This was eventually solved by adding in the pygame.event.pump function into key places. This allows pygame to process its internal events such as talking with the OS. Without this, the event queue is paused for too long and the program gets flagged as not responding, the screen freezes, and bad things happen.
Relevant fixed code (only one line different):
def disappear(self):
self.surface.blit(self.BACKUPSURF,(self.x,self.y))
pygame.display.update()
pygame.event.pump() #So the display updates properly, stops it from freezing and making you miss messages. This allows pygame to do some internal events such as talking to the OS. Otherwise, if the event queue has been paused for too long, the OS will treat it as not responding, and bad things happen.
sleep(0.1)
I'm doing some processing tasks on a medium-sized (1.7 Mb) Persian text corpus. I want to make lists of three set of characters in the text:
alphabets
white spaces (including newline, tab, space, no-breaking space and etc.) and
punctuation.
I wrote this:
# -*- coding: utf8 -*-
TextObj = open ('text.txt', 'r', encoding = 'UTF8')
import string
LCh = LSpc = LPunct = []
TotalCh = TotalPunct = TotalSpc = 0
TempSet = 'ابپتثجچحخدذرزژسشصضطظعغفقکگلمنوهی'
#TempSet variable holds alphabets of Persian language.
ReadObj = TextObj.read ()
for Char in ReadObj:
if Char in TempSet: #This's supposed to count & extract alphabets only.
TotalCh += 1
LCh.append (Char)
elif Char in string.punctuation: #This's supposed to count puncts.
TotalPunct += 1
LPunct.append (Char)
elif Char in ('', '\n', '\t'): #This counts & extracts spacey things.
TotalSpc += 1
LSpc.append (Char)
else: #This'll ignore anything else.
continue
But when I try:
print (LPunct)
print (LSpc)
I tried this code on both Linux and Windows 7. On both of them, the result is not what I expected at all. The punctuation's and space's lists, both contains Persian letters.
Another question:
How can I improve this condition elif Char in ('', '\n', '\t'): so that it covers all kind of space family?
On line 3 you've assigned all the lists to be the same list!
Don't do this:
LCh = LSpc = LPunct = []
Do this:
LCh = []
LSpc = []
LPunct = []
The string class has whitespace built in.
elif Char in string.whitespace:
TotalSpc += 1
LSpc.append (Char)
In your example you didn't actually put a space in your '' character which also may be causing it to fail. Shouldn't this be ' '?
Also, take into account the other answer here, this code is not very pythonic.
I'd write it like this:
# -*- coding: utf8 -*-
import fileinput
import string
persian_chars = 'ابپتثجچحخدذرزژسشصضطظعغفقکگلمنوهی'
filename = 'text.txt'
persian_list = []
punctuation_list = []
whitespace_list = []
ignored_list = []
for line in fileinput.input(filename):
for ch in line:
if ch in persian_chars:
persian_list.append(ch)
elif ch in string.punctuation:
punctuation_list.append(ch)
elif ch in string.whitespace:
whitespace_list.append(ch)
else:
ignored_list.append(ch)
total_persian, total_punctuation, total_whitepsace = \
map(len, [persian_list, punctuation_list, whitespace_list])
First of all as a more pythonic way for dealing with files you better to use with statement for opening the files which will close the file at the end of the block.
Secondly since you want to count the number of special characters within your text and preserve them separately, you can use a dictionary with the list names as the keys and relative characters in a list as value. Then use len method to get the length.
And finally for check the membership in whitespaces you can use string.whitespace method.
import string
TempSet = 'ابپتثجچحخدذرزژسشصضطظعغفقکگلمنوهی'
result_dict={}
with open ('text.txt', 'r', encoding = 'UTF8') as TextObj :
ReadObj = TextObj.read ()
for ch in ReadObj :
if Char in TempSet:
result_dict['TempSet'].append(ch)
elif Char in string.punctuation:
result_dict['LPunct'].append(ch)
elif Char in string.whitespace:
result_dict['LSpc'].append(ch)
TotalCh =len(result_dict['LSpc'])