How can I resolve this whitespace issue in my recurssion question - python

LAB: Drawing a right side up triangle
Write a recursive function called draw_triangle() that outputs lines of * to form a right side up isosceles triangle. Function draw_triangle() has one parameter, an integer representing the base length of the triangle. Assume the base length is always odd and less than 20. Output 9 spaces before the first * on the first line for correct formatting.
Hint: The number of * increases by 2 for every line drawn.
Ex: If the input of the program is:
3
the function draw_triangle() outputs:
*
***
Ex: If the input of the program is:
19
the function draw_triangle() outputs:
*
***
*****
*******
*********
***********
*************
***************
*****************
*******************
Note: No space is output before the first * on the last line when the base length is 19.
I have been able to figure out the recursion part but I cant figure out getting the right white space to the left of the triangle

If I understand your problem correctly, you see that the "top" of the triangle, always has one * in it. Then if the base of the triangle is n, the "top" row should have n - 1 spaces in it.
Continuing the pattern you can see that with every row under the top, you add 2 *'s. Then any given row will have n - 2r - 1 spaces if r is the row (starting from the top, r = 0).
Here's the cool part, since you know n is odd (given in question) and 2r is definitely even, then n - 2r - 1 is always going to be even. Call half this number the "whitespace amount" and print out that amount of spaces for each row (and remember, the row r starts from 0).
Here's some pseudo code
def print_triangle(width, row):
if 2 * row + 1 == width: # if you are in the last row
for i < 2 * row + 1:
print("*") # print the *
return # break out of recursion
else:
for i < (width - 2 * row - 1) / 2:
print(" ") # print whitespace
for i < 2 * row + 1:
print("*") # print the *
return print_triangle(width, row + 1) # recursive call
of course there are many more ways to do this, some of which will have more concise code, but hopefully this pseudo code helps you understand the logic behind the program.

You can't just have a single variable for recursion:
This code would help you:
def draw_triangle(n,i):
if(n<=0):
return
print(" "*(n//2),end="")
print("*"*i)
draw_triangle(n-2,i+2)
draw_triangle(19,1)
Output:
*
***
*****
*******
*********
***********
*************
***************
*****************
*******************
Hope this helps you. Here i=1 since you need to print 1 star at the begining.
For your weird request to have 9 space for all input :))
def draw_triangle(n,i=1,s=9):
if(i>n):
return
print(" "*s+"*"*i)
draw_triangle(n,i+2,s-1)
draw_triangle(3)
Here i represents how many stars in first line and s represent space in first line.
Output:
*
***

Related

Create a Bowtie Pattern with Python 3.0

Given a odd positive integer h, greater than or equal to 5, create a bowtie pattern with h rows and 2h columns.
input: 5
output:
* *
*** ***
**********
*** ***
* *
or
input: 7
output:
* *
*** ***
***** *****
**************
***** *****
*** ***
* *
I created code that only works for one given value of h but I'm not sure how to make it functional for any value of h. I also tried taking advantage of the symmetry so I made only half of the bowtie.
h = input()
n = int(h)
x = "*"
space = " "
print(x)
print(-(-n // 2)*x)
print(n*x)
print(-(-n // 2)*x)
print(x)
You can build up the top half by left and right justifying the * repeated as many times as necessary (we use range with a step for this as the first row will have 1 *, the next 2 more, the next 2 more again up until we reach N) padded left and right with width n, eg:
n = int(input())
top = [('*' * i).ljust(n) + ('*' * i).rjust(n) for i in range(1, n, 2)]
This gives you a top (for n=5) of:
['* *', '*** ***']
Then, we print the top, the middle (which is always * repeated N*2 times) and then top in reverse order for the bottom separated by newlines, eg:
print(*top, '*' * n * 2, *reversed(top), sep='\n')
Gives you (n=5):
* *
*** ***
**********
*** ***
* *
Or for (n=11):
* *
*** ***
***** *****
******* *******
********* *********
**********************
********* *********
******* *******
***** *****
*** ***
* *
Symmetry tells you that the left and the right have the same number of *. It also tells you that the middle row is all stars (n * 2), and that each row the same distance above and below the middle row has the same size. Further, as you move away from the center, you lose 4 stars total, 2 from each side.
The two secrets to coding this concise are to 1) number the rows symmetrical, not from 1 to n, but from -n//2 to n//2; and 2) to think of the rows as a number of spaces drawn on a background of *s, rather than a number of *s surrounding spaces.
Once you figure out how many spaces are in each row (call it f(i), based on the value of i in for i in range(-n//2, n//2+1): ..., you can draw that row with (" "*f(i)).center(2*n, "*").
it will work for any odd number
h = input()
n = int(h)
i = 1
if(n%2)!=0 and n > 4:
halfmark= n//2
str=""
while i <= n:
if(i<=halfmark):
blank = ' '* (4*(halfmark +1-i))
elif i > (halfmark+1):
blank = ' '*(4*(i-(halfmark+1)))
else:
blank = ''
star = '*'*((2*n-len(blank))//2)
str = star+blank+star
print(str)
i +=1

Python Slot Machine: Calculating Line Payouts

I'm a Python newbie attempting to create a slot machine simulator that mimics the payouts of the real machines. I'm running into an issue in calculating the line payouts, and I'm sure there's a smarter way of iterating through the lines and calculating them.
Defining some constants that I'll be using:
SymbolMap = ["Boats","Bonus","Buoys","Clams","Light Houses","Lobsters","Scatter","Seagulls","Starfish","Tuna","Wilds"]
#The ints in reels below are a simpler way to express the SymbolMap above
Reels = [[9,8,3,4,6,3,8,1,5,6,2,3,8,2,3,8,5,4,3,10,7,8,10,1,3,0,8,9,3,8,9,5,3,8,0,4,3,8,0,9,2,7,5,3,8,0,7],
[3,2,4,3,2,4,1,7,3,0,7,9,0,1,8,7,10,1,7,4,5,10,2,3,1,7,3,6,5,9,7,6,8,3,0,5,7,3,1,8,7,2,4,3,9,7,0],
[0,8,3,1,4,0,5,8,1,4,8,1,9,8,3,7,8,10,1,4,7,8,9,3,0,9,8,1,9,4,8,6,4,5,7,8,6,2,9,5,1,8,4,7,2,0,9],
[7,9,2,7,6,2,8,7,9,10,2,9,8,5,7,9,10,5,4,2,7,0,3,8,4,7,0,3,2,7,0,4,8,9,7,2,8,3,2,7,8,3,5,10,2,7,8],
[3,10,0,5,2,8,4,9,8,4,7,10,9,2,0,3,9,2,8,3,6,2,8,9,3,2,0,4,9,5,4,7,3,5,8,0,4,9,7,8,4,3,5,7,8,3,7]]
# Lines are the row to look for on each reel. i.e. Lines[0] is a straight line of the 2nd row.
# Lines[3] starts in top left corner of matrix, and forms inverted V shape.
Lines = [[1,1,1,1,1],
[0,0,0,0,0],
[2,2,2,2,2],
[0,1,2,1,0],
[2,1,0,1,2],
[2,2,1,0,0],
[0,0,1,2,2],
[1,2,1,0,1],
[1,0,1,2,1],
[2,1,1,1,0],
[0,1,1,1,2],
[1,2,2,1,0],
[1,0,0,1,2],
[1,1,2,1,0],
[1,1,0,1,2]]
#Payouts are how many credits won for symbols in a row. For example, Symbols[0] is Boats.
#2 boats is 0 credits, 3 boats is 25 credits, 4 boats is 100 credits, 5 boats is 500 credits.
#They must be continuous and from left to right. I.e. BOAT-BOAT-CLAM-BOAT-BOAT on a payline wins 0.
#Similarly, CLAM-CLAM-BOAT-BOAT-BOAT wins 0.
Payouts = [[0,25,100,500],
[0,0,0,0],
[0,25,100,500],
[0,5,30,200]]
#Initializing a 3X5 matrix to represent reels
SpinValues = [[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0]]
#Initializing message
Message = ''
#Initializing TotalWin
TotalWin = 0
Spin logic, which properly generates a 3X5 matrix of random numbers. Is there a better way to handle the "if first 3 symbols match" portion, since I'll have to repeat again for 4 symbols and 5 symbols? Since each line is only entitled to one payout, I'll start with the 5 symbol payouts, then work down toward 2. I started with 3 because it's the most common and will be easiest to test. I'll also have to account for a wild equaling any symbol, which I haven't tried to tackle yet. Likewise, there is a scatter pay (meaning if you have X number of Scatter symbols anywhere in the matrix, you get a payout. That part will be easy). There is also a bonus game, which I'll be working on later:
def spin(linesPlayed, wager):
for i, object in enumerate(Reels):
length = len(Reels[i])
StopValue = random.randint(0,length-1)
SpinValues[1][i] = Reels[i][StopValue]
if StopValue == 0:
SpinValues[0][i] = Reels[i][-1]
else:
SpinValues[0][i] = Reels[i][StopValue - 1]
if StopValue == len(Reels[i])-1:
SpinValues[2][i] = Reels[i][0]
else:
SpinValues[2][i] = Reels[i][StopValue +1]
print(SpinValues[0])
print("\n")
print(SpinValues[1])
print("\n")
print(SpinValues[2])
for i in range(linesPlayed):
#if first 3 symbols match
if SpinValues[Lines[i][0]] == SpinValues[Lines[i][1]] == SpinValues[Lines[i][2]]:
PayTable(i,wager,3,SpinValues[Lines[i][0]])
#if first 4 symbols match
#if first 5 symbols match
#handle scatter pay
#wilds?
#handle bonus trigger
Handling wins:
def PayTable(i,wager,symbolCount,symbol):
LineWin = Payouts[symbol][symbolCount] * wager
TotalWin += Payouts[symbol][symbolCount] * wager
Message += "Line " + str(i) +" wins " + str(LineWin) + " credits with " + str(symbolCount) + " " + SymbolMap[symbol] + "!" + "\n"
I'm getting the error that both TotalWin and Message are undefined. I thought that I could defined them globally up top?
You need to use the global keyword in each function to access variables defined in a parent.
For example:
def PayTable(i,wager,symbolCount,symbol):
global TotalWin
global Message

Iteratively Drawing a 'Bow Tie' in Python

I am trying to make a code that draws a bow tie with a given input.
A bow tie:
* *
*** ***
**********
*** ***
* *
I am working on 2 methods here. Can anyone tell me if I am on the correct path? I seem to be lost...
num = int(input("Enter an odd number greater than 4: "))
row = 1
row_space = row*2-1
space_tot = num*2 - row_space*2
stars = int((num*2 - space_tot)/2)
space = ""
for x in range(num):
print("*"*stars+" "*space_tot+"*"*stars)
row += 1
space_tot -= 2
def triangle(n):
for x in range(n,0,2):
print ('*'*x)
for x in range(n,0,-2):
print ('*'*x)
n -= 1
triangle(num)
num = int(input("Enter an odd number greater than 4: "))
center = (num - 1)//2
for row in range(num):
nspaces = 2*abs(row - center)
nstars = num - nspaces
print nstars*'*' + 2*nspaces*' ' + nstars*'*'
How it works
Let's look at the desired output (with row numbers added) for the case num=5:
0 * *
1 *** ***
2 **********
3 *** ***
4 * *
Let us think about this as a left half and a right half. Observe each half has num stars in the center row. The number of spaces in the center row is zero. The number of spaces in each half increases by two for each row that we move away from the center. Expressed mathematically:
nspaces = 2*abs(row - center)
Each half is num columns wide. So, if a half has nspaces spaces, then the number of stars in that half is:
nstars = num - nspaces
Having computed both of those, it is only a matter of printing it all out:
print nstars*'*' + 2*nspaces*' ' + nstars*'*'
This is done once for each row.
When you are learning Python, it is good to look through its library functions. In Python, everything is an object. And every object has methods. Here is a link to everything you need to know about strings in Python.
https://docs.python.org/2/library/string.html
You'll get a number of functions here which directly relate to your problem. The more familier you are with the objects in Python, the better you become in programming in Python. This is true for any language. If you want to become better at a particular language, learn its specifics.
For your problem, you can learn about the methods ljust(), rjust() and join(). How do you use them?
In [126]: '[' + 'abcd'.ljust(10) + ']'
Out[126]: '[abcd ]'
In [127]: '[' + 'abcd'.rjust(10) + ']'
Out[127]: '[ abcd]'
In [134]: '-][-'.join(['A', 'list', 'of', 'strings'])
Out[134]: 'A-][-list-][-of-][-strings'
Of course, you can replace the 'abcd' with '*'s. In this case, you have,
In [129]: ('*'*3).ljust(5) + ('*'*3).rjust(5)
Out[129]: '*** ***'
Now, you just replace the 3 with a counter for your choice. Note that your numbers increments in 2s. Before you do that, I hope you know about list comprehension. If not, you can just learn about it here:
https://docs.python.org/2/tutorial/datastructures.html#list-comprehensions
In [132]: [('*'*i).ljust(5) + ('*'*i).rjust(n) for i in range(1, n+2, 2)]
Out[132]: ['* *', '*** ***', '**********']
Let us now save this in a variable, and join them together ...
In [135]: l = [('*'*i).ljust(5) + ('*'*i).rjust(n) for i in range(1, n+2, 2)]
In [137]: print '\n'.join(l)
* *
*** ***
**********
Of course, you need the other half as well. For that you will need to use nearly all of the list you created above as l. Notice:
In [138]: l # Original list
Out[138]: ['* *', '*** ***', '**********']
In [139]: l[:-1] # Original list - the last value in the list
Out[139]: ['* *', '*** ***']
In [140]: l[:-1][::-1] # reverse that one
Out[140]: ['*** ***', '* *']
In [141]: l + l[:-1][::-1] # join the reversed list to the original list
Out[141]: ['* *', '*** ***', '**********', '*** ***', '* *']
Finally, we can join the two lists and form the bwotie:
In [143]: print '\n'.join(l + l[:-1][::-1])
* *
*** ***
**********
*** ***
* *
So in summary, you need 3 lines to print a bowtie:
n = 5 # Or a user input here ...
l = [('*'*i).ljust(5) + ('*'*i).rjust(n) for i in range(1, n+2, 2)]
print '\n'.join(l + l[:-1][::-1])
Hopefully, you see that it pays to go through the documentation in Python. You will be able to get a lot of useful methods, which can make coding very easy. The more familier you are with Python libraries, the better your coding. Most of these libraries are fine-tuned for a particular system, so it will be difficult to beat their effeciency as well. So you get twice the advantage, for the same amount of effort :).
Good luck with your programming.
def triangle(n):
for x in range(n,0,2):
print ('*'*x)
for x in range(n,0,-2):
print ('*'*x)
n -= 1

Python 3 Beginner - Iterating Triangle

I am going through a past test and the output of the code is this:
Enter the height:
5
5
44
333
2222
11111
I have to write down the code - so far I know how to make a normal triangle with:
for i in range(5):
print('*'*i)
*
**
***
****
My main question is how do I get the body if the triangle to iterate over the numbers?
So what would the code of the first triangle be?
Help would be appreciated:)
The code for this is virtually the same, you just need to change the number of times you print each character, and change the * that you are printing to a number.
for i in range(5):
print(str(5-i) * (i+1))
This generates:
5
44
333
2222
11111
To make it right aligned, like in your example, just use string multiplication on a space character.
for i in range(5):
print(' ' * (4-i) + str(5-i) * (i+1))
This will get you:
5
44
333
2222
11111
You can use str:
for i in range(5):
print(str(i)*i)
Some of the other answers have been essentially correct, but this one right justifies your triangle like the original output.
def print_triangle(rows):
for i in range(rows + 1):
print((str(rows + 1-i)*i).rjust(rows))
height = 5
for i in range(height, 0, -1):
empty_chars = ' ' * (i - 1)
filler_chars = str(i) * (height - i + 1)
print('{}{}'.format(empty_chars, filler_chars))
Formatted string & spacing with an external array and a negated variable.
def height(num):
rangenum=range(num+1)
for i in rangenum:
print(("%"+str(num)+"s")%(i*str(rangenum[-i])))
print("%(spacing as a number)s"%(a string))
returns
(spacing as a number)-(a string)
example:
print("%10s"%"this")
returns:
" this"
side note:
%-(a number)s
is right justified.
(though python tries to cut down the millions of ways to do the same thing, there still are thousands)
https://docs.python.org/2/tutorial/inputoutput.html

Asterisk Pyramid Not Spaced Correctly

Here is my code but I'm having trouble getting the pyramid to be spaced correctly like a pyramid and also to only have odd number of asterisks per line.
Output when you enter 7 for the base should be
*
***
*****
*******
This is my code:
base = int(input( 'enter an odd number for the base : ' ) )
for i in range( 0, base ):
print '*' * i
You could use str.center():
for i in range(1, base + 1, 2):
print ('*' * i).center(base)
but do use a step size of 2, and adjust your range. The first line starts with 1 star always, and range() doesn't include the last value.
For 7, that means you want to print 1, 3, 5 and 7 stars, incrementing by 2 each iteration.
There are some errors in your code:
since you're using print '...' instead of function print, you may be in python2, where raw_input is needed instead of input;
range(1, base+1, 2) is needed instead, for your sample output.
Demo:
In [6]: base = int(raw_input( 'enter an odd number for the base : ' ) )
...: for i in range(1, base+1, 2):
...: print ('*' * i).center(base)
enter an odd number for the base : 7
*
***
*****
*******

Categories