It is possible to add an additional sentence / word to the line

I had to create code similar to this several times:

if condition(): word = " not" else: word = "" print "A five ounce bird could{0} carry a one pound coconut".format(word) 

I split the problem down to my bones here, in "practice" there would be additional variables for "A" , "five" , "bird" , "A" , "one" and "coconut" so that they could all change, and together with them added multiple s-es and something else.

It always struck me as something less than satisfaction. The extra space needed before "not" and the lack of a space before {0} both irk, but since I don't want it to have two spaces if word empty, I see no other way to do this.

The creation of two separate messages is interrupted with DRY and is sometimes not viable due to the number of possible combinations.

Is there a more elegant way to do this?

+4
source share
7 answers

Create a list of words, insert if necessary, and then ' '.join(words) them.

If there are commas / periods, build a sentence structure:

 [['If', 'there', 'are', 'periods'], ', ', ['build', 'a', 'sentence', 'structure'], '.'] 

with corresponding spaces in the interpolation (space after the decimal point, space before the bracket, ...), and then ' '.join() words inside the groups and ''.join() separate groups. (Thanks @Alfe for the suggestion, combining words and groups in different ways).

+3
source

Two separate messages are interrupted with DRY

If you care about i18n , then creating two separate messages is probably the only sensible way to do this.

+2
source

For the " not" case " not" keep it simple:

 print "A five ounce bird could{0} carry a one pound coconut".format(" not" if condition() else "") 
+1
source

I would do...

 word = ("could" if not condition() else "could not") print "A five ounce bird {0} carry a one pound coconut".format(word) 

: R

Edit: for the general case that you want, I would go for composition. For instance. (ok, this is too Go4 and simplified to my liking, but makes a point):

 class Agglutinator(list): def __str__(self): return self._separator.join(str(x) for x in self) class Paragraph(Agglutinator): """Returns dot separated sentences""" _separator = '. ' class Sentence(Agglutinator): """Returns comma separated clauses""" _separator = ', ' class Clause(Agglutinator): """Returns space separated words""" _separator = ' ' c1 = Clause(["A", "number", "of", "words", "make", "a", "clause"]) c2 = Clause(["and", "a", "number", "of", "clauses", "make", "a", "sentence"]) c3 = Clause(["A", "collection", "of", "sentences", "makes", "a", "paragraph"]) s1 = Sentence([c1, c2]) s2 = Sentence([c3]) print Paragraph([s1, s2]) 

which gives you:

 A number of words make a clause, and a number of clauses make a sentence. A collection of sentences makes a paragraph 

Having developed a bit, you can make Sentence capitalize the first word, etc.

+1
source

Since the rules in which there should be space and where not are clear in English (and in other languages ​​that I know), you can use a simple list of all parts of the sentence (for example, ['If', 'there', 'are', 'commas', ',', 'we', 'insert', 'them', '.'] ), and then write a specialized join function that applies the English rules about where spaces should be inserted (for example, between words, after commas, before opening parentheses ...).

+1
source

Another way to handle this, but I'm not sure if this is what you are looking for

 word = "not" print "A five ounce bird could{0} carry a one pound coconut".format(" "+word if condition() else "") 

Ok, another approach. But in fact, almost all of them are similar or the same ...

 def format_word(word): if word: return " " + word else: return "" print "A five ounce bird could{0} carry a one pound coconut".format(format_word(word)) 

But, probably, all of them will look annoying, since they are actually similar ...

The final dirty approach could be:

 if condition(): word = "not" else: word = "" wrd = "A five ounce bird could {0} carry a one pound coconut".format(word) print wrd.replace(" ", " ") # replace all double spaces with singular one... 

but yes, it's dirty too ...

+1
source

I will add another possibility that I just thought about myself. Subclass string.Formatter and add a custom converter so you can enter

 fmt = MyFormatter() print fmt("Problem {not!w} solved", not="") 

The formatting element will then remove the space in front of all fields using the !w converter if the variable was empty / not specified. This requires at least vformat and convert_field , but this should be fully feasible.

0
source

Source: https://habr.com/ru/post/1413924/


All Articles