0
\$\begingroup\$

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.

toolic
14.6k5 gold badges29 silver badges204 bronze badges
asked Feb 15, 2024 at 11:55
\$\endgroup\$
1
  • 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\$ Commented Feb 15, 2024 at 12:25

2 Answers 2

3
\$\begingroup\$

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.

answered Feb 15, 2024 at 12:29
\$\endgroup\$
3
\$\begingroup\$

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
 
 /) /) /) 
(/ _ // // ___
/ )__(/_(/_(/_(_) 
answered Feb 18, 2024 at 14:47
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.