What would a good code of this look like, or is it good enough?
import sys
from pyfiglet import Figlet
import random
figlet = Figlet()
list = figlet.getFonts()
def main():
if len(sys.argv) == 1:
text = input("Input: ")
randomfont = random.choice(list)
figlet.setFont(font=randomfont)
elif len(sys.argv) == 3:
if sys.argv[2] in list:
figlet.setFont(font=sys.argv[2])
if sys.argv[1] == "-f" or sys.argv[1] == "--font":
text = input("Input: ")
else:
sys.exit("Please input a correct response")
else:
sys.exit("Please input a correct response.")
else:
sys.exit("Please input a correct response.")
print(figlet.renderText(text))
main()
I'm calling random to choose a random font from the list of fonts.
Is there any easier way to set the font?
Also, I have called upon input
on 2 separate occasions. Is there a efficient way to do this? Even if I did it using try
and except
, wouldn't I need the same?
Here, I have called 3 else
and exit
statements to basically call upon the same statement. It didn't feel right to me.
-
3\$\begingroup\$ I highly suggest you take the tour that is offered when you join a new community, so you can learn how it works and what is expected of your posts. Also read How to Ask in the help center. Doing so hopefully prevents the negative experience you get when your question gets downvoted and closed for not following the site rules. In particular I’m referring to the lack of review context. In this site we review complete code, we don’t answer specific questions about snippets of code. codereview.meta.stackexchange.com/a/3652 \$\endgroup\$Cris Luengo– Cris Luengo2024年02月15日 12:25:07 +00:00Commented Feb 15, 2024 at 12:25
2 Answers 2
You should add header documentation to your code to let users know what it does and how you expect it to be used. For example, if your script is named myscript.py
:
'''
Usage:
This will prompt you to enter a string, then print it using a random font:
myscript.py
This will prompt you to enter a string, then print it using the given font:
myscript.py -f xtimes
'''
list
is a built-in type for python. You should choose a better name for the variable, such as fonts
.
You use the same error string to represent different error types:
"Please input a correct response"
You should make each of the error messages unique so that the user knows what went wrong and how to fix it.
You can call input
just once, right before you print
the figlet, with some adjusted logic for the -f
option.
Consider using the standard argparse library instead of creating your own code to parse the command line.
Here is the code with some of the suggestions:
'''
Usage:
This will prompt you to enter a string, then print it using a random font:
myscript.py
This will prompt you to enter a string, then print it using the given font:
myscript.py -f xtimes
'''
import sys
from pyfiglet import Figlet
import random
figlet = Figlet()
fonts = figlet.getFonts()
def main():
if len(sys.argv) == 1:
randomfont = random.choice(fonts)
figlet.setFont(font=randomfont)
elif len(sys.argv) == 3:
if sys.argv[2] in fonts:
figlet.setFont(font=sys.argv[2])
if sys.argv[1] != "-f" and sys.argv[1] != "--font":
sys.exit("Please input a correct response1")
else:
sys.exit("Please input a correct response2.")
else:
sys.exit("Please input a correct response3.")
text = input("Input: ")
print(figlet.renderText(text))
main()
You should replace response1
with some message that is unique to this error type. The same for response2
and response3
.
Replace use of sys.argv
with argparse
. Among many other reasons, it autogenerates help, and can inform the user of the permitted fonts if they try to select an invalid one.
Don't instantiate figlet
at the global level. You can call getFonts
at the global level, but call it on the FigletFont
class method, and don't name it list
. When you do locally instantiate Figlet
, pass the font as a constructor argument rather than setting it later.
Wrap your main()
call in a __main__
guard.
When you pass a prompt to input()
, it should be somewhat more informative than Input:
- even Text:
would be more helpful.
Add an interpreter hashbang at the top of the file.
Suggested
#!/usr/bin/env python3
import argparse
from pyfiglet import Figlet, FigletFont
import random
FONTS = FigletFont.getFonts()
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description='Render ASCII text')
parser.add_argument(
'-f', '--font', metavar='',
required=False, choices=FONTS, default=random.choice(FONTS),
help='Font to render (or omit for random)',
)
parser.add_argument(
'text', nargs='?',
help='Text to render (or omit to prompt)',
)
return parser.parse_args()
def main() -> None:
args = parse_args()
text = args.text or input('Text: ')
fig = Figlet(font=args.font)
print(fig.renderText(text), end='')
if __name__ == '__main__':
main()
Output
$ python 289532.py --help
usage: 289532.py [-h] [-f] [text]
Render ASCII text
positional arguments:
text Text to render (or omit to prompt)
options:
-h, --help show this help message and exit
-f , --font Font to render (or omit for random)
$ python 289532.py -f noexist
usage: 289532.py [-h] [-f] [text]
289532.py: error: argument -f/--font: invalid choice: 'noexist' (choose from 'sbooki', 'xcouri', 'stampate', 'stforek', 'mirror', 'peaks', 'baz__bil', 'dotmatrix', 'isometric3', 'xbritei', 'broadway_kb', 'dcs_bfmo', 'slant_relief', 'convoy__', 'morse2', 'crawford2', 'tubular', 'ttyb', 'eca_____', 'etcrvs__', 'a_zooloo', 'future_7', 'beer_pub', 'rockbox_', 'amc_3_line', 'twin_cob', 'grand_pr', 'merlin1', 'madrid', 'test1', 'bigchief', '5x8', 'bell', 'bright', 'ansi_shadow', 'char4___', 'speed', 'big_money-sw', 'char3___', 'fire_font-k', 'gothic', 'runic', 'georgia11', 'delta_corps_priest_1', 'pawn_ins', 'big_money-se', 'octal', 'fender', 'trashman', 'pebbles', 'wet_letter', 'univers', 'amc_untitled', 'fbr12___', 'amc_slider', 'cour', 'xsansbi', 'alphabet', 'sbookb', 'flower_power', 'xbritebi', 'dos_rebel', 'cli8x8', 'rci_____', 'tengwar', 'drpepper', 'konto_slant', 'lazy_jon', 'tombstone', 'amc_razor', 'rad_phan', 'tec1____', 'xtty', 'taxi____', 'basic', 'future_6', 'britebi', 'eftitalic', 'ugalympi', 'danc4', 'heroboti', 'green_be', 'tsn_base', 'radical_', 'clr6x6', 'charact4', 'slscript', 'unarmed_', 'bubble', 'banner', 'alligator2', 'clr6x8', 'small_shadow', 'the_edge', 'dwhistled', 'arrows', 'knob', 'notie_ca', 't__of_ap', 'lockergnome', 'marquee', 'smscript', 'sansbi', 'nancyj-underlined', 'clr5x10', 'xhelv', 'fp2_____', 'sblood', 'coil_cop', 'high_noo', 'alpha', 'charact1', 'letterw3', 'caus_in_', 'ticksslant', 'fair_mea', 'calvin_s', 'merlin2', 'clr7x8', 'pacos_pe', 'new_asci', 'fire_font-s', 'stop', 'blocky', 'magic_ma', 'pawp', 'vortron_', 'isometric1', 'tanja', 'slant', 'nvscript', 'hills___', 'computer', 'c1______', 'old_banner', 'eftipiti', 'konto', 'sweet', 'raw_recu', 'varsity', 'yie_ar_k', 'efti_robot', 'xcourbi', 'graceful', 'utopia', 'r2-d2___', 'fp1_____', 'aquaplan', '1row', 'xsbookb', 'demo_1__', 'com_sen_', 'amc_neko', 'pepper', 'c_ascii_', 'char2___', 'impossible', 'odel_lak', 'clr8x8', '5lineoblique', 'future_5', 'eftiwall', 'asc_____', 'eftirobot', 'hypa_bal', 'tec_7000', 'top_duck', 'o8', 'fourtops', 'mike', 'colossal', 'road_rai', 'tinker-toy', 'mshebrew210', 'chunky', 'maxfour', 'starwars', 'zone7___', 'doom', 'xbriteb', 'house_of', 'sansb', 'future_8', 'bolger', 'stacey', 'xtimes', 'amc_thin', 'demo_m__', 'ogre', 'js_cursive', 'moscow', 'stellar', 'platoon2', 'nancyj', 'thick', 'ts1_____', 'wavy', 'bigfig', 'js_capital_curves', 'rozzo', 'double', 'braced', 'fbr_stri', 'smshadow', 'cards', 'future_3', 'banner3-D', 'lil_devil', 'panther_', 'ntgreek', 'eftifont', 'utopiai', 'digital', 'thin', 'sansi', 'bloody', 'xchartr', 'georgi16', 'super_te', 'chiseled', 'clr8x10', 'twopoint', 'nancyj-improved', 'bear', 'js_stick_letters', 'big_money-ne', 'pod_____', 'diamond', 'small_caps', 'jacky', 'ticks', 'gauntlet', 'filter', 'finalass', 'funky_dr', 'twisted', 'clr4x6', 'future_2', 'ghost_bo', 'home_pak', 'b1ff', 'atc_gran', '64f1____', 'calgphy2', 'cyberlarge', 'henry_3d', 'cosmike', 'hyper___', 'e__fist_', 'faces_of', '6x9', 'katakana', 'straight', 'epic', 'charact3', 'amc_slash', 'lean', 'britei', 'devilish', 'amc_3_liv1', 'binary', 'xhelvbi', 'fuzzy', 'z-pilot_', 'tomahawk', 'cybermedium', 'rotated', 'puffy', 'tecrvs__', 'skateord', 'mnemonic', 'street_s', 'ripper!_', 'cursive', 'smkeyboard', 'rad_____', 'clr5x6', 'outrun__', 'star_strips', 'clb6x10', 'big', 'kik_star', 'advenger', 'relief', 'banner4', 'helvbi', 'courb', 'crawford', 'rastan__', 'mig_ally', 'c2______', 'sm______', 'rounded', 'runyc', 'flipped', 'pyramid', 'stencil2', 'hex', 'space_op', 'bulbhead', 'war_of_w', 'rainbow_', 'brite', 'ascii___', 'standard', 'jerusalem', 'ghost', 'briteb', 'eftiwater', 'mcg_____', 'lcd', 'weird', 'helvi', 'charact6', 'future_1', 'assalt_m', 'helv', 'modular', 'cygnet', 'spliff', 'skate_ro', 'isometric2', 'roman___', 'js_block_letters', 'fraktur', 'xsbook', 'triad_st', 'bubble_b', 'chartri', 'xsbooki', 'stronger_than_all', 'sub-zero', 'ok_beer_', 'fireing_', 'stencil1', 'star_war', 'lexible_', 'usaflag', 'shadow', 'soft', '4max', 'yie-ar__', 'blocks', 'smslant', '5x7', 'charact2', 'asslt__m', 'xcourb', 'diet_cola', 'kgames_i', 'ti_pan__', 'puzzle', 'inc_raw_', 'stick_letters', 'eftichess', 'small_slant', 'ansi_regular', 'b_m__200', 'fairligh', 'wow', 'usa_____', 'xhelvi', 'greek', 'xttyb', 'smtengwar', 'mad_nurs', 'barbwire', 'atc_____', 'sketch_s', 'xbrite', 'morse', 'helvb', 'italic', 'charset_', 'coinstak', 'double_shorts', 'rowancap', 'char1___', 'utopiab', 'os2', 'ebbs_2__', 'xsansb', 'xsbookbi', 'contrast', 'cola', 'amc_tubes', 'spc_demo', 'subteran', 'dancing_font', 'rally_sp', '3d_diagonal', 'thorned', '3x5', 'patorjk-hex', 'fbr_tilt', 'heavy_me', 'sbook', 'horizontal_left', 'c_consen', '6x10', 'couri', 'nipples', 'cricket', 'larry3d', 'platoon_', 'keyboard', 'slide', 'line_blocks', 'phonix__', 'letters', 'battlesh', 'modern__', 'js_bracket_letters', 'rev', 'script__', 'tiles', 'skateroc', 'mayhem_d', 'demo_2__', 'rot13', 'nancyj-fancy', 'characte', '4x4_offr', 'zig_zag_', 'smisome1', 'stampatello', '3d-ascii', 'poison', 'muzzle', 'clr7x10', 'f15_____', 'small_poison', 'relief2', 'rectangles', 'hieroglyphs', 'heart_right', "patorjk's_cheese", 'sans', 'shimrod', 'krak_out', 'tty', 'clb8x8', 'xsans', 'sl_script', 'clr5x8', 'broadway', 'caligraphy', 'master_o', 'benjamin', 'big_money-nw', 'linux', 'deep_str', 'italics_', 'nscript', 'flyn_sh', 'train', 'banner3', 'goofy', 'rammstein', 'acrobatic', 'ghoulish', 'hollywood', 'ivrit', 'sbookbi', 'script', 'ebbs_1__', 'glenyn', '1943____', 'd_dragon', 'doh', 'nfi1____', '3-d', 'crazy', 'mini', 'timesofl', 'npn_____', 'fun_face', 'bubble__', 'kban', 'ascii_new_roman', 'joust___', 'whimsy', 'santa_clara', 'p_skateb', 'usa_pq__', 'p_s_h_m_', 'type_set', 'cybersmall', 'stealth_', 'catwalk', 'clr6x10', 'trek', 'def_leppard', 'defleppard', 'heart_left', 'letter_w', 'avatar', 'courbi', 'xchartri', 'amc_aaa01', 'horizontal_right', 'chartr', 'amc_razor2', 'times', 'this', 'rally_s2', 'red_phoenix', 'ucf_fan_', 'druid___', 'threepoint', 'jazmine', 'electronic', 'serifcap', 'xcour', 'tsalagi', 'xhelvb', 'isometric4', 'decimal', 'future_4', 'short', 'tav1____', 'fbr2____', 'tsm_____', 'fbr1____', 'elite', 'xsansi', 'cosmic', 'rok_____', 'alligator', 'battle_s', 'graffiti', 'charact5', 'fantasy_', 'term', 'swamp_land', 'gothic__', 'hades___', 'small', 'gradient', 'clb8x10', 'block', 'invita', 'roman', 'icl-1900', 'fun_faces', 'contessa', 'swan', 'utopiabi', 'rampage_')
$ python 289532.py -f invita hello
/) /) /)
(/ _ // // ___
/ )__(/_(/_(/_(_)