Python-based fancy text generator h1>
In the process of browsing the web, we often see various "unusual" characters, such as:
These characters will always be based on ordinary characters, with many strange symbols attached. The basic principle is the superposition of Unicode combined with diacritics and ordinary text. If you want to make such a text generator, you first need to understand how such text is encoded using Unicode
Basic theory
The role of Unicode
At the beginning, people used ASCII codes with a length of only 1 byte to represent 128 characters, each of which corresponds to a code, for example: binary code 01000001 2 _2 2 represents the character 'A', then in the program, the character 'A' is saved with a binary sequence like 01000001
Later, as the demand increased, the ASCII codes that could only represent 128 characters gradually became "not enough": ASCII codes obviously did not include Chinese, Japanese, and Korean characters. If you want to encode these characters, you need Separately formulate a new encoding rule, so Unicode was born
Unicode uses more bytes to include languages from all over the world. In this way, under the rules of Unicode, any country's text can have a corresponding encoding. In other words, after using Unicode, you can use national languages in the program (not necessarily one of the 128 characters specified in the ASCII code)
Unicode combined diacritics
In Unicode encoding, there is a category called "combining diacritics", which is the "root of all evil" for these weird-shaped characters: combining ordinary characters with these combining diacritics, something that may never have been seen before will happen. the spectacle
Open the python idle interface and enter:
sss = "\u0041\u030A"print(sss)
This phenomenon can be observed:
Notice that not only an A is output, but also a circle is added on top of A! \u0041 is the Unicode code of A, and \u030A is a combined additional symbol "∘ \circ ∘". When these two symbols are combined, the circle will not occupy a separate position, but will be combined with A stand up!
If this \u030A is copied multiple times, more and more circles can be continuously generated above A, thus achieving the effect of "passing through the screen":
The above interface is the result of running the Console in the browser’s developer tools, but in Python’s idle, the displayed text has a height limit, so basically only the first layer of circles is kept, resulting in visual effects that are not not good. In fact, in the chat interface of QQ and WeChat, the height of the text is also limited, so when copied in, you can only see four or five layers at most, which is not visually shocking enough
In addition to circles, there are many other combined diacritics, all of which can be superimposed with the previous text. The Unicode encoding combined with additional symbols is located between 0300-036F of the 0th plane (I don’t understand the specific concept, but it is represented by \u at the beginning), and there are 112 characters in total. https://unicode-table.com/cn/ blocks/combining-diacritical-marks/ You can search for the symbols corresponding to these Unicode codes on this website, which is very helpful for subsequent bells and whistles.
Programming ideas
After briefly mentioning about Unicode, it is now possible to design a generator for such text
Sort out the current known information:
1. Ordinary text + Unicode combined with additional symbols = add symbols to ordinary text
2. The encoding of Unicode combined with additional symbols is located between 0300-036F on the 0th plane, that is Encoded between \u0300-\u036F
So if you want to put a bunch of weird symbols around your words, you just have to put these Unicode conjugations after each word. The more Unicode symbols are added, the more chaotic it looks (according to the actual measurement, some symbols will be superimposed, while some symbols will be superimposed):
In this way, the idea in the program is very clear: let the user input a string first, then traverse each character in the string in turn, and add a certain number of Unicode combining symbols after each character. Finally, just output the new string. The pseudo code is expressed as follows:
process convertStr(string) newString <- "" // Initialize an empty string for i <- 1 to length(string) randomUnicode <- Randomly generate the specified number of Unicode combination symbols corresponding to the code newString < ;- newString + string[i] + randomUnicode end for return newString
Regarding the random generation of Unicode, since I don't know much about these 112 combination symbols, I randomly select between \u0300-\u036F here. In addition, it should also be possible for users to specify the density of these combination symbols (the number of combination symbols placed on the same text), otherwise too few will have no effect, and too many may burst the screen again (a few years ago in the QQ group I have seen a message that seems to use a lot of Unicode combination symbols, but after 90% of people saw that message, QQ crashed...)
After having an idea, the next step is to implement it
Program Implementation
Analysis
The user's operation is carried out in the graphical interface, therefore, a boundary class is first required: the user interface class. As for the processing of strings, a control class can be used alone, so another control class can be added: string processing class. The corresponding class diagram is as follows:
Design
There is only one main interaction between these two classes: the user interface class sends a string to the string processing class, lets the string processing class process the string, and then receives the processed string
Therefore, assign the method to the string processing class: convertString(str, density)——string processing, and assign the method to the user interface class: convert(str, density)——send the string to the string processing class for later The operator processes the string and returns the processed string
In addition, the string is input from the user interface class, because the length is usually very small, it does not need to exist as a separate entity class, so it can be directly used as a member of the user interface class. In summary, the constructed class diagram is as follows:
Implementation
Control class ProString
Firstly, the control class ProString is constructed, and there is only one method, which is the realization of the procedure convertStr(string, density) in the above pseudo code. Create a new file ProString.py:
import randomclass ProString: '''Process string receive from user's interface class''' @staticmethod def convertString(string, density): newString = "" lengthOfStr = len(string) for i in range(lengthOfStr) : randomUnicode = "" for j in range(density): randomUnicode += ("\\u03" + str(int(random.random() * 7)) + str([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'A', 'B', 'C', 'D', 'E', 'F'][int(random.random() * 16)])) # distinguish Output letters, numbers if('a' <= string[i] <= 'z' or 'A' <= string[i] <= 'Z' or '0' <= string[i] <= '9'): part = string[i] else: part = str(string[i].encode("unicode_escape"))[-7:-1] newString += (part + randomUnicode) return newString< /code>
Because of various cheating problems, letters and numbers need to be separated separately, and Chinese characters need to be converted into unicode characters first, so there is a very puzzling if-else statement
The generation of randomUnicode is relatively stupid, but the most direct way that can be thought of is this way...
Feel free to write a test.py to call this procedure:
from ProString import *a = ProString.convertString("aaa is", 10)print(a)
got the answer:
a\u0363\u032D\u036B\u0314\u032F\u030E\u0359\u0317\u0337\u030Da\u0328\u0322\u0319\u0309\u035E\u0356\u0356\u0321\u033D\ u0349a\u033B\ u0331\u036A\u0306\u030A\u0306\u0317\u0325\u032E\u0306\u662f\u032F\u036E\u0323\u034B\u0349\u0351\u032D\u0369\u0322\u0323
This is exactly the desired return result, copy it to the console of the browser developer tool to see the effect:
Chinese characters are not displayed, but it doesn't matter, it can still be displayed normally in other places
Next to the user interface class:
User interface class Main
Here, qt is used to design the graphical interface, first of all, an induced template:
Import Sysfrom Pyside2.qtuitools Import QUILOADERFROM PYSIDE2.qtwidgets Imide2.qtcore Import qfile, qiodeviceIF __Name__ == "__main__": app = qapplication (sys.argv) ui_file_name = "form.ui" ui_file = qfile = qfile (ui_file_name) if not ui_file.open(QIODevice.ReadOnly): print("Cannot open {}: {}".format(ui_file_name, ui_file.errorString())) sys.exit(-1) loader = QUiLoader() window = loader.load(ui_file) ui_file.close() if not window: print(loader.errorString()) sys.exit(-1) window.show() sys.exit(app.exec_())
Using this code, you can let python load a graphical interface file named form.ui and open it when you run Main.py
Now, first design the graphical interface form.ui. This process is done in qt creator:
Qt creator can provide a good visual interface design environment, and there is still an open source (free) version, it is worth a try
The designed window interface is as follows:
Then, in Main.py, add a method to call ProString.convertString:
def convert(): inputString = window.textEdit.toPlainText() #Exclude empty string if(inputString == ""): return #Exclude symbol density of illegal input density = window.lineEdit.text() try: density = int(density) except: window.plainTextEdit.setPlainText("The symbol density should be a number!") return # Normal execution outputString = ProString.convertString(inputString, density) outputString = outputString.encode("utf-8" ).decode("unicode_escape") window.plainTextEdit.setPlainText(outputString)
And associate this method with the button:
window.pushButton.clicked.connect(convert)
At this point, the production of the generator is complete, and the following is the running effect:
Effect display
Put it in QQ and try:
ohhhhhhhhhhhhhhhhhhh
It is found through actual measurement that if you want to ensure readability, setting the symbol density to 8 is almost the same, and if it is more, it will affect the reading of the text...
In the end, I found out after finishing it that, in QQ, just change a few more lines, and the symbols in the following lines can be pushed to the top. This method can be used to make up for the height limit...
source code
form.ui
<?xml version="1.0" encoding="UTF-8"?><ui version="4.0"> <class>widget</class> <widget class="QWidget" name="widget"> < ;property name="geometry"> <rect> <x>0</x> <y>0</y> <width>1000</width> <height>750</height> < ;/rect> </property> <property name="minimumSize"> <size> <width>1000</width> <height>750</height> </size> </property> <property name="maximumSize"> <size> <width>1000</width> <height>750</height> </size> </property> <property name="windowTitle "> <string>Form</string> </property> <widget class="QPushButton" name="pushButton"> <property name="geometry"> <rect> <x> 840</x> <y>10</y> <width>151</width> <height>61</height> </rect> </property> <property name="font" > <font> <family>Italian</family> <pointsize>20</pointsize> </font> </property> <property name="text"> <string> </string> </property> </widget> <widget class="QLineEdit" name="lineEdit"> <property name="geometry"> <rect> <x>720< /x> <y>10</y> <width>61</width> <height>61</height> </rect> </property> <property name="font"> <font> <pointsize>20</pointsize> </font> </property> <property name="text"> <string>10</string> </property> <property name="maxLength"> <number>2</number> </property> </widget> <widget class="QLabel" name="label"> <property name="geometry"> <rect> <x>540</x> <y>10</y> <width>181</width> <height>61</height> </rect> </property> ; <property name="font"> <font> <family>单体</family> <pointsize>20</pointsize> </font> </property> text"> <string>symbol density</string> </property> </widget> <widget class="QLabel" name="label_2"> <property name="geometry"> <rect> <x>10</x> <y>10</y> <width>211</width> <height>61</height> </rect> </property> <property name="font"> <font> <family> italics</family> <pointsize>20</pointsize> </font> </property> <property name="text "> <string>Text to be converted</string> </property> </widget> <widget class="QTextEdit" name="textEdit"> <property name="geometry"> <rect> <x>220</x> <y>10</y> <width>311</width> <height>61</height> </rect> </property> <property name="font"> <font> <pointsize>12</pointsize> </font> </property> </widget> <widget class="QPlainTextEdit" name="plainTextEdit "> <property name="geometry"> <rect> <x>10</x> <y>80</y> <width>981</width> <height>661< /height> </rect> </property> <property name="font"> <font> <pointsize>20</pointsize> </font> </property> </widget> ; </widget> <resources/> <connections/></ui>
Main.py H1> Import Sysfrom Pyside2.qtuitools Import QULOADERFROM PYSIDE2.qtwidgets ImplicationFrom Pyside2.qtcore Import QFile EFROM PROSTRING Import *DEF Convert (): InputString = Window.textedit.toplaintext () # inputString == ""): return # Exclude the symbol density of illegal input density = window.lineEdit.text() try: density = int(density) except: window.plainTextEdit.setPlainText("The symbol density should be a number! ") return # Normal execution outputString = ProString.convertString(inputString, density) outputString = outputString.encode("utf-8").decode("unicode_escape") window.plainTextEdit.setPlainText(outputString)if __name__ == "__main__" : app = QApplication(sys.argv) ui_file_name = "form.ui" ui_file = QFile(ui_file_name) if not ui_file.open(QIODevice.ReadOnly): print("Cannot open {}: {}".format(ui_file_name, ui_file .errorString())) sys.exit(-1) loader = QUiLoader() window = loader.load(ui_file) ui_file.close() if not window: print(loader.errorString()) sys.exit(-1) window.pushButton.clicked.connect( convert) window.show() sys.exit(app.exec_())
ProString.py
< code>import randomclass ProString: '''Process string receive from user's interface class''' @staticmethod def convertString(string, density): newString = "" lengthOfStr = len(string) for i in range(lengthOfStr): randomUnicode = " " for j in range(density): randomUnicode += ("\\u03" + str(int(random. random() * 7)) + str([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'A', 'B', 'C', 'D', 'E', 'F'][int(random.random() * 16)])) # distinguish between letters and numbers if('a' <= string[i] <= 'z' or 'A' <= string[i] <= 'Z' or '0' <= string[i] <= ' 9'): part = string[i] else: part = str(string[i].Private message Xiaobian 01 to get a lot of Python learning materials
Import Sysfrom Pyside2.qtuitools Import QULOADERFROM PYSIDE2.qtwidgets ImplicationFrom Pyside2.qtcore Import QFile EFROM PROSTRING Import *DEF Convert (): InputString = Window.textedit.toplaintext () # inputString == ""): return # Exclude the symbol density of illegal input density = window.lineEdit.text() try: density = int(density) except: window.plainTextEdit.setPlainText("The symbol density should be a number! ") return # Normal execution outputString = ProString.convertString(inputString, density) outputString = outputString.encode("utf-8").decode("unicode_escape") window.plainTextEdit.setPlainText(outputString)if __name__ == "__main__" : app = QApplication(sys.argv) ui_file_name = "form.ui" ui_file = QFile(ui_file_name) if not ui_file.open(QIODevice.ReadOnly): print("Cannot open {}: {}".format(ui_file_name, ui_file .errorString())) sys.exit(-1) loader = QUiLoader() window = loader.load(ui_file) ui_file.close() if not window: print(loader.errorString()) sys.exit(-1) window.pushButton.clicked.connect( convert) window.show() sys.exit(app.exec_())
Private message Xiaobian 01 to get a lot of Python learning materials
Articles are uploaded by users and are for non-commercial browsing only. Posted by: Lomu, please indicate the source: https://www.daogebangong.com/en/articles/detail/fancy%20text%20generator.html
评论列表(196条)
测试