How to make pyramid of a string? - python

I want to make a pyramid of a string for an exercise.
I just don't know how to do it.
For example:
string = "these***are***just***random***words*"
and the pyramid I want to make is:
t
hes
e***a
re***ju
st***rand
om***words*
How do I do this?
def draw_pyramid(string, size):
if size > 15:
size = 15
if size < 5:
size = 5
l = string * size
for i in range(size + 1):
stars = i
p = l[0:stars]
spaces = size - i
print(" " * spaces + p)
def main():
size = int(input("How many layers do you want it to be?: "))
string = "these***are***just***random***words*"
draw_pyramid(string, size)
if __name__ == '__main__':
main()
Result:
t
th
the
thes
these
these*
these**
these***
these***a
these***ar

You can use string.center() to get the strings nicely aligned in the center. To get the right characters from l I use a start and an end variable:
def draw_pyramid(string, size):
if size > 15:
size = 15
if size < 5:
size = 5
length = size * 2 - 1
l = string * size
start = 0
end = 0
for stars in range(1, size + 1):
end += stars * 2 - 1
p = l[start:end]
start = end
print(p.center(length))
Output :
How many layers do you want it to be?: 10
t
hes
e***a
re***ju
st***rand
om***words*
these***are**
*just***random*
**words*these***a
re***just***random*

The way you are indexing l is wrong, based on what you want to achieve. If you study your desired output, you see that on the first row you want the substring l[0:1], on the second row l[1:4], then l[4:9], l[9:16] etc. The starting index is the sum of the first i odd elements, i.e. 1+3+5+.. and the stopping index is the sum of the first i+1 odd elements. Thus, at each step, you want l[i**2:(i+1)**2], with i starting at 0.
So your function should look like this
def draw_pyramid(string, size):
if size > 15:
size = 15
if size < 5:
size = 5
l = string * size
for i in range(size + 1):
p = l[i**2:(i+1)**2]
spaces = size - i
print(" " * spaces + p)
and it produces the desired output

Related

Draw a centered triforce surrounded by hyphens using Python

I want to draw a triangle of asterisks from a given n which is an odd number and at least equal to 3. So far I did the following:
def main():
num = 5
for i in range(num):
if i == 0:
print('-' * num + '*' * (i + 1) + '-' * num)
elif i % 2 == 0:
print('-' * (num-i+1) + '*' * (i + 1) + '-' * (num-i+1))
else:
continue
if __name__ == "__main__":
main()
And got this as the result:
-----*-----
----***----
--*****--
But how do I edit the code so the number of hyphens corresponds to the desirable result:
-----*-----
----***----
---*****---
--*-----*--
-***---***-
*****-*****
There's probably a better way but this seems to work:
def triangle(n):
assert n % 2 != 0 # make sure n is an odd number
hyphens = n
output = []
for stars in range(1, n+1, 2):
h = '-'*hyphens
s = '*'*stars
output.append(h + s + h)
hyphens -= 1
pad = n // 2
mid = n
for stars in range(1, n+1, 2):
fix = '-'*pad
mh = '-'*mid
s = '*'*stars
output.append(fix + s + mh + s + fix)
pad -= 1
mid -= 2
print(*output, sep='\n')
triangle(5)
Output:
-----*-----
----***----
---*****---
--*-----*--
-***---***-
*****-*****
Think about what it is you're iterating over and what you're doing with your loop. Currently you're iterating up to the maximum number of hyphens you want, and you seem to be treating this as the number of asterisks to print, but if you look at the edge of your triforce, the number of hyphens is decreasing by 1 each line, from 5 to 0. To me, this would imply you need to print num-i hyphens each iteration, iterating over line number rather than the max number of hyphens/asterisks (these are close in value, but the distinction is important).
I'd recommend trying to make one large solid triangle first, i.e.
-----*-----
----***----
---*****---
--*******--
-*********-
***********
since this is a simpler problem to solve and is just one modification away from what you're trying to do (this is where the distinction between number of asterisks and line number will be important, as your pattern changes dependent on what line you're on).
I'll help get you started; for any odd n, the number of lines you need to print is going to be (n+1). If you modify your range to be over this value, you should be able to figure out how many hyphens and asterisks to print on each line to make a large triangle, and then you can just modify it to cut out the centre.

swap output the order of the digits

I have one code here
and need to change the order of the digits
import math
def sucet_cisel(number):
bla: int = 0
while number > 0:
xyzpremenna = number % 10
bla += xyzpremenna
number = (number - xyzpremenna) / 10
return bla
def digit_root(n):
if n == 0: return 0
return (n - 1) % 9 + 1
if __name__ == '__main__':
n = int(input("od čisla:"))
m = int(input("do čisla:"))
for i in range(1,m + 1):
sucet: int = math.floor(sucet_cisel(n*i))
t=(n*i)*(2)
x=' ';
print(n,"*",i,"=",n*i,(x*4),"*2","=",t,sep='')
they need to add () to this code so that in each result where there are 4 numbers they are moved
therefore print (t) need this script to run at that number
t=(ni)(2)
and the result of this to turn into this code
val = list(str(i))
digit = val.pop(-3)
new = int(''.join(val+[digit]))
od čisla:2554
do čisla:4505
2554*4505=11505770 *2=23011540
23011540
23011405
the script stops at the number I enter where is the problem?
20*1=20 *2=40
20*2=40 *2=80
20*3=60 *2=120
20*4=80 *2=160
20*5=100 *2=200
20*6=120 *2=240
20*7=140 *2=280
20*8=160 *2=320
20*9=180 *2=360
20*10=200 *2=400
20*11=220 *2=440
20*12=240 *2=480
20*13=260 *2=520
20*14=280 *2=560
20*15=300 *2=600
20*16=320 *2=640
20*17=340 *2=680
20*18=360 *2=720
20*19=380 *2=760
20*20=400 *2=800
this makes a code if I give
n = int (input ("from number:"))
m = int (input ("to number:"))
n20
m20
however, if in this script there is i
val = list (page (s))
digit = val.pop (-3)
new = int (''. join (val + [digit]))
does it calculate only one result where is the error?
Very similar to the answer from Tim Roberts, but using slices and format strings.
n = 12345678
s = str(n)
x = int(f"{s[:-5]}{s[::-1][:4]}")
s is '12345678', s[:-5] is '1234', s[::-1] is '87654321', and s[::-1][:4] is '8765'. Put it all together and x is 12348765.
OK, let's rewrite your problem to "given a number of greater than 4 digits, I want that same number but with all permutations of the last 4 digits.
import itertools
def permute(number):
val = str(number)
prefix = val[:-4]
for combo in itertools.permutations(val[-4:]):
yield int(prefix+''.join(combo))
print(list(permute(12345678)))

Benford's law program

I have to write a program that proves Benford's Law for two Data lists. I think I have the code down for the most part but I think there are small errors that I am missing. I am sorry if this is not how the site is supposed to be used but I really need help. Here is my code.
def getData(fileName):
data = []
f = open(fileName,'r')
for line in f:
data.append(line)
f.close()
return data
def getLeadDigitCounts(data):
counts = [0,0,0,0,0,0,0,0,0]
for i in data:
pop = i[1]
digits = pop[0]
int(digits)
counts[digits-1] += 1
return counts
def showResults(counts):
percentage = 0
Sum = 0
num = 0
Total = 0
for i in counts:
Total += i
print"number of data points:",Sum
print
print"digit number percentage"
for i in counts:
Sum += i
percentage = counts[i]/float(Sum)
num = counts[i]
print"5%d 6%d %f"%(i,num,percentage)
def showLeadingDigits(digit,data):
print"Showing data with a leading",digit
for i in data:
if digit == i[i][1]:
print i
def processFile(name):
data = getData(name)
counts = getLeadDigitCounts(data)
showResults(counts)
digit = input('Enter leading digit: ')
showLeadingDigits(digit, data)
def main():
processFile('TexasCountyPop2010.txt')
processFile('MilesofTexasRoad.txt')
main()
Again sorry if this is not how I am supposed to use this site. Also, I can only use programming techniques that the professor has showed us so if you could just give me advice to clean up the code as it is I would really appreciate it.
Also, here are a few lines from my data.
Anderson County 58458
Andrews County 14786
Angelina County 86771
Aransas County 23158
Archer County 9054
Armstrong County 1901
Your error is coming from this line:
int(digits)
This doesn't actually do anything to digits. If you want to convert digits to an integer, you have to re-set the variable:
digits = int(digits)
Also, to properly parse your data, I would do something like this:
for line in data:
place, digits = line.rsplit(None, 1)
digits = int(digits)
counts[digits - 1] += 1
Lets walk though one cycle of your code and I think you'll see what the problem is. I'll be using this file here for data
An, 10, 22
In, 33, 44
Out, 3, 99
Now getData returns:
["An, 10, 22",
"In, 33, 44",
"Out, 3, 99"]
Now take a look the first pass though the loop:
for i in data:
# i = "An, 10, 22"
pop = i[1]
# pop = 'n', the second character of i
digits = pop[0]
# digits = 'n', the first character of pop
int(digits)
# Error here, but you probably wanted digits = int(digits)
counts[digits-1] += 1
Depending on how your data is structured, you need to figure out the logic to extract the digits you expect to get from your file. This logic might do better in the getData funciton, but it mostly depends on the specifics of your data.
Just to share here a different (and maybe more step-by-step) code. It's RUBY.
The thing is, Benford's Law doesn't apply when you have a specific range of random data to extract from. The maximum number of the data set that you are extracting random information from must be undetermined, or infinite.
In other words, say, you used a computer number generator that had a 'set' or specific range from which to extract the numbers, eg. 1-100. You would undoubtedly end up with a random dataset of numbers, yes, but the number 1 would appear as a first digit as often as the number 9 or any other number.
**The interesting** part, actually, happens when you let a computer (or nature) decide randomly, and on each instance, how large you want the random number to potentially be. Then you get a nice, bi-dimensional random dataset, that perfectly attains to Benford's Law. I have generated this RUBY code for you, which will neatly prove that, to our fascination as Mathematicians, Benford's Law works each and every single time!
Take a look at this bit of code I've put together for you!
It's a bit WET, but I'm sure it'll explain.
<-- RUBY CODE BELOW -->
dataset = []
999.times do
random = rand(999)
dataset << rand(random)
end
startwith1 = []
startwith2 = []
startwith3 = []
startwith4 = []
startwith5 = []
startwith6 = []
startwith7 = []
startwith8 = []
startwith9 = []
dataset.each do |element|
case element.to_s.split('')[0].to_i
when 1 then startwith1 << element
when 2 then startwith2 << element
when 3 then startwith3 << element
when 4 then startwith4 << element
when 5 then startwith5 << element
when 6 then startwith6 << element
when 7 then startwith7 << element
when 8 then startwith8 << element
when 9 then startwith9 << element
end
end
a = startwith1.length
b = startwith2.length
c = startwith3.length
d = startwith4.length
e = startwith5.length
f = startwith6.length
g = startwith7.length
h = startwith8.length
i = startwith9.length
sum = a + b + c + d + e + f + g + h + i
p "#{a} times first digit = 1; equating #{(a * 100) / sum}%"
p "#{b} times first digit = 2; equating #{(b * 100) / sum}%"
p "#{c} times first digit = 3; equating #{(c * 100) / sum}%"
p "#{d} times first digit = 4; equating #{(d * 100) / sum}%"
p "#{e} times first digit = 5; equating #{(e * 100) / sum}%"
p "#{f} times first digit = 6; equating #{(f * 100) / sum}%"
p "#{g} times first digit = 7; equating #{(g * 100) / sum}%"
p "#{h} times first digit = 8; equating #{(h * 100) / sum}%"
p "#{i} times first digit = 9; equating #{(i * 100) / sum}%"

Draw inverted triangle of asterisk by using nested loops in Python

I've to write a program that get a series of valid inputs from user and then uses the nested loops to draw the inverted triangle.
I've managed to work out the triangle but I struggling on inverted triangle. Can anyone give me some hint on how to draw the inverted triangle by only print a single charater of * and without using * * rowlength?
Global constant
L = 10
Get rows number
rows = int(input ( 'Enter a number of rows: ' ) )
Rows cannot less than 10 or greater than 100
while rows < 10 or rows > 100:
if rows < L:
print( 'The number is too Low.' )
else:
print( 'The number is too high.' )
rows = int(input ( 'Enter the correct value: ' ) )
Display the triangle
for r in range(rows):
for c in range(r + 1):
print('*', end='')
print()
This is very similar to a question I had to do for class once, but we were implementing it in C. Actually, quite cool to go back now, reimplement it in python and look at the difference.
The problem we had in class was very similar. My python code to make this work is:
while True:
rows = input('Enter the number of rows: ')
if 3 <= rows <= 33:
break
else:
continue
padding = ' '*rows
while rows > 0:
print(padding[rows:] + '*'*rows)
rows = rows - 1
-- modified below, to print outline of inverted triangle:
# print the outline of an inverted triangle:
height = rows
# inner padding for min height (3)
inner_buffer = [0, 1, 3]
while len(inner_buffer) <= rows:
inner_buffer.append(inner_buffer[-1]+2)
while height > 0:
outer_padding = ' '*(rows - height)
if height == 1:
print(outer_padding + '*')
else:
inner_padding = ' '*(inner_buffer.pop()-2)
print(outer_padding + '*' + inner_padding + '*')
height = height - 1
There has got to be a more elegant want to code this, but simply a working hack to see if we are on the right track.
New revision below:
-- function that will produce a regular triangle, or inverted triangle as defined
def get_rows():
while True:
rows = input('Enter the number of rows: ')
if 3 <= rows <= 33:
return rows
def triangle(rows, regular=False, invert=True):
if invert:
height = -1 * rows
else:
height = 0
# inner padding for min height (3)
inner_buffer = [0, 1, 3]
while len(inner_buffer) <= rows:
inner_buffer.append(inner_buffer[-1]+2)
level = 0
while level <= rows:
outer_padding = ' '*(rows - abs(height))
if height == 0:
print(outer_padding + '*')
else:
inner_padding = ' '*( inner_buffer[ abs(height) ] )
print(outer_padding + '*' + inner_padding + '*')
height += 1
level += 1
Let me know :)

leading number groups between two numbers

(Python) Given two numbers A and B. I need to find all nested "groups" of numbers:
range(2169800, 2171194)
leading numbers: 21698XX, 21699XX, 2170XX, 21710XX, 217110X, 217111X,
217112X, 217113X, 217114X, 217115X, 217116X, 217117X, 217118X, 2171190X,
2171191X, 2171192X, 2171193X, 2171194X
or like this:
range(1000, 1452)
leading numbers: 10XX, 11XX, 12XX, 13XX, 140X, 141X, 142X, 143X,
144X, 1450, 1451, 1452
Harder than it first looked - pretty sure this is solid and will handle most boundary conditions. :) (There are few!!)
def leading(a, b):
# generate digit pairs a=123, b=456 -> [(1, 4), (2, 5), (3, 6)]
zip_digits = zip(str(a), str(b))
zip_digits = map(lambda (x,y):(int(x), int(y)), zip_digits)
# this ignores problems where the last matching digits are 0 and 9
# leading (12000, 12999) is same as leading(12, 12)
while(zip_digits[-1] == (0,9)):
zip_digits.pop()
# start recursion
return compute_leading(zip_digits)
def compute_leading(zip_digits):
if(len(zip_digits) == 1): # 1 digit case is simple!! :)
(a,b) = zip_digits.pop()
return range(a, b+1)
#now we partition the problem
# given leading(123,456) we decompose this into 3 problems
# lows -> leading(123,129)
# middle -> leading(130,449) which we can recurse to leading(13,44)
# highs -> leading(450,456)
last_digits = zip_digits.pop()
low_prefix = reduce(lambda x, y : 10 * x + y, [tup[0] for tup in zip_digits]) * 10 # base for lows e.g. 120
high_prefix = reduce(lambda x, y : 10 * x + y, [tup[1] for tup in zip_digits]) * 10 # base for highs e.g. 450
lows = range(low_prefix + last_digits[0], low_prefix + 10)
highs = range(high_prefix + 0, high_prefix + last_digits[1] + 1)
#check for boundary cases where lows or highs have all ten digits
(a,b) = zip_digits.pop() # pop last digits of middle so they can be adjusted
if len(lows) == 10:
lows = []
else:
a = a + 1
if len(highs) == 10:
highs = []
else:
b = b - 1
zip_digits.append((a,b)) # push back last digits of middle after adjustments
return lows + compute_leading(zip_digits) + highs # and recurse - woohoo!!
print leading(199,411)
print leading(2169800, 2171194)
print leading(1000, 1452)
def foo(start, end):
index = 0
is_lower = False
while index < len(start):
if is_lower and start[index] == '0':
break
if not is_lower and start[index] < end[index]:
first_lower = index
is_lower = True
index += 1
return index-1, first_lower
start = '2169800'
end = '2171194'
result = []
while int(start) < int(end):
index, first_lower = foo(start, end)
range_end = index > first_lower and 10 or int(end[first_lower])
for x in range(int(start[index]), range_end):
result.append(start[:index] + str(x) + 'X'*(len(start)-index-1))
if range_end == 10:
start = str(int(start[:index])+1)+'0'+start[index+1:]
else:
start = start[:index] + str(range_end) + start[index+1:]
result.append(end)
print "Leading numbers:"
print result
I test the examples you've given, it is right. Hope this will help you
This should give you a good starting point :
def leading(start, end):
leading = []
hundreds = start // 100
while (end - hundreds * 100) > 100:
i = hundreds * 100
leading.append(range(i,i+100))
hundreds += 1
c = hundreds * 100
tens = 1
while (end - c - tens * 10) > 10:
i = c + tens * 10
leading.append(range(i, i + 10))
tens += 1
c += tens * 10
ones = 1
while (end - c - ones) > 0:
i = c + ones
leading.append(i)
ones += 1
leading.append(end)
return leading
Ok, the whole could be one loop-level deeper. But I thought it might be clearer this way. Hope, this helps you...
Update :
Now I see what you want. Furthermore, maria's code doesn't seem to be working for me. (Sorry...)
So please consider the following code :
def leading(start, end):
depth = 2
while 10 ** depth > end : depth -=1
leading = []
const = 0
coeff = start // 10 ** depth
while depth >= 0:
while (end - const - coeff * 10 ** depth) >= 10 ** depth:
leading.append(str(const / 10 ** depth + coeff) + "X" * depth)
coeff += 1
const += coeff * 10 ** depth
coeff = 0
depth -= 1
leading.append(end)
return leading
print leading(199,411)
print leading(2169800, 2171194)
print leading(1000, 1453)
print leading(1,12)
Now, let me try to explain the approach here.
The algorithm will try to find "end" starting from value "start" and check whether "end" is in the next 10^2 (which is 100 in this case). If it fails, it will make a leap of 10^2 until it succeeds. When it succeeds it will go one depth level lower. That is, it will make leaps one order of magnitude smaller. And loop that way until the depth is equal to zero (= leaps of 10^0 = 1). The algorithm stops when it reaches the "end" value.
You may also notice that I have the implemented the wrapping loop I mentioned so it is now possible to define the starting depth (or leap size) in a variable.
The first while loop makes sure the first leap does not overshoot the "end" value.
If you have any questions, just feel free to ask.

Categories

Resources