I have some bugs in cantor set code that I cannot locate. The idea is that given array of numbers you recursively remove 1/3 of middle elements and recurse on two sides and repeat until certain threshold.
Here is the code
import math
full = list(range(80))
l = list(range(80))
threshold = 2
def printl():
for i in full:
if i in l:
print("*", end='')
else:
print(" ", end='')
print()
def cantor(lo, hi):
lowi = math.ceil( (hi-lo) * 1/3 + lo)
highi = int( (hi-lo) * 2/3 + lo)
if len(l[lo:hi]) < threshold:
return
printl()
del l[lowi:highi]
cantor(lo, lowi)
cantor(lowi+1, hi)
cantor(0, len(l)-1)
I get super weird result, not sure why...
A tricky problem -- I calculated the pieces and recursively zip'd them together into an array which I then dump to the terminal:
from math import log
def cantor(length, threshold):
if length >= threshold:
sequence = cantor(length // 3, threshold)
blanks = [" " * (length // 3)] * int(log(length, 3) + 1) # estimate and let zip toss extras
return ["*" * length] + [a + b + c for a, b, c in zip(sequence, blanks, sequence)]
return []
length = 81
threshold = 1
print(*cantor(length, threshold), sep='\n')
OUTPUT
> python3 test.py
*********************************************************************************
*************************** ***************************
********* ********* ********* *********
*** *** *** *** *** *** *** ***
* * * * * * * * * * * * * * * *
>
I think you should change the order of processing the slices to go from last to first because recursing into the lower indexes will invalidate the positions that the prior recursion has for lowi and hi:
cantor(lowi+1, hi)
cantor(lo, lowi)
cantor(0, len(l)-1)
You may want to check the end of ranges in your subscripts because the end of a range is exclusive. i.e. l[2:7] does not include index #7.
Related
Trying to get the hollow square example done using list comprehensions ...
side = int(input())
for i in range(side):
for j in range(side):
print('*' if(i == 0 or i == side - 1 or j == 0 or j == side - 1) else ' ', end='')
print()
my goal is to have the nested loop also in the comprehension format but can't figure it out.
tried it like this.. but it prints out each side of the square in a one line...
side = int(input())
square= ["*" if (i == 0 or i == side - 1 or j == 0 or j == side - 1) else " " for i in range(side) for j in range(side)]
print(''.join(square),end='')
you could do it like this:
side = 5
s = "\n".join("*"+c*(side-2)+"*" for c in f"*{'*':>{side-1}}")
print(s)
*****
* *
* *
* *
*****
or let the print function provide the end of lines:
s = ["*"+c*(side-2)+"*" for c in f"*{'*':>{side-1}}"]
print(*s,sep="\n")
*****
* *
* *
* *
*****
Could be also done with the comprehension inside the print call:
side = 5
s = f"*{'*':>{side-1}}"
print(*(s.replace(' ',c) for c in s),sep="\n")
*****
* *
* *
* *
*****
or
print(*("*"+"* "[i%(n-1)>0]*(side-2)+"*" for i in range(side)),sep="\n")
*****
* *
* *
* *
*****
If you need to use nested comprehensions, you could do this:
s = [["*" if {r,c}&{0,side-1} else " " for c in range(side)]
for r in range(side)]
print(*map(''.join,s),sep="\n")
*****
* *
* *
* *
*****
Here you go
side = int(input())
s = ''.join(['{}{}'.format('*' if (i == 0 or i == side - 1 or j == 0 or j == side - 1) else ' ', '\n' if j == side - 1 else '') for i in range(side) for j in range(side)])
print(s)
This uses format() to output a possible \n if we've reached the end of a row. Format in this case works like "{}{}".format('hey', '123') --> "hey123". You could probably just append the two strings but this looks nicer IMO. The first {} in format is for the * or , the second {} is either empty '' or a newline \n. This makes it print properly.
Cool?
Using nested list comprehension:
side = int(input())
square = ''.join([''.join(["*" if (i * j == 0 or i == side - 1 or j == side - 1) else " " for i in range(side)]) + '\n' for j in range(side)])
print(square)
Prints:
5
*****
* *
* *
* *
*****
I'm trying to translate a loop to a recursive algorithm. Fairly simple, I've just hadn't been able to make it ignore the n value when summing up the values, like range does.
This is the iterative function:
def function(n):
total=0
for i in range(1,n,2):
total += i
print(total)
function(5) # Output: 4
This is the recursive I've tried:
def function1(n):
if n==1:
return n
else:
return n+function1(n-2)
function(5) # Output: 9
So function1 does sum the n when it should be ignored. Cause range() does not include the stop number.
Then, I tried:
def f1(n):
def f_recursive(n):
if n==1 or n==2:
return 1
elif n==0:
return 0
else:
return n + f_recursive(n - 2)
return f_recursive(n) - n
print(f1(5)) # Output: 4 Yeiii!!
But then I realised, that only works for odd numbers. Not for even. If f1(6) then you get 4 when it should be 9, because it ends up being 11-6= 9.
So silly me I tried:
def f1(n):
def f_recursive(n):
if n==1 or n==2:
return 1
elif n==0:
return 0
elif n%2 == 0:
return n + f_recursive(n - 3)
elif n%2 == 1:
return n + f_recursive(n - 2)
return f_recursive(n) - n
print(f1(6))
Which of course also did not work. Am I not understanding recursion properly here?
The tricky part is excluding the upper bound. If the upper bound is your only parameter n, you have to know when it's the first call, and when it's an intermediate (recursive) call. Alternatively, if inner functions are okay, you could instead just count from 1 up until you hit n:
def function1(n):
def inner(i):
return 0 if i >= n else i + inner(i + 2)
return inner(1)
You want to compute the sum of all odd integers from 1 up to, but not including, n.
This leaves 2 possibilities:
If n is <= 1, there are no numbers to sum, so the sum is 0.
The highest number that might be included in the list is n-1, but only if it is odd. Either way, the rest of the sum is "the sum of all odd integers from 1 up to, but not including, n-1" (sound familiar?)
This translates to:
def f1(n):
if n <= 1:
return 0
else:
isOdd = (n-1)%2==1
return f1(n-1) + (n-1 if isOdd else 0)
The problem with your recursion is that you're returning n rather than the value in the range (list) that you're currently on, this poses a problem since n is not inclusive within the range and should not be added to the final total
Ideally you need to reverse the logic and traverse it the same way your range does
def func(start,end, step):
if(start >= end):
return 0
return start + func(start + step, end, step)
You just have to recognize the three types of ranges you might be adding up.
range(1, n, 2) where n <= 1: The empty range, so the sum is 0
range(1, n, 2) where n > 1 and n is even: the range is 1, ..., n-1. (E.g. range(1, 6, 2) == [1, 3, 5])
range(1, n, 2) where n > 1 and n is odd: the range is 1, ..., n-2 (E.g., range(1, 5, 2) == [1, 3]
Translating this to code is straightforward:
def f_recursive1(n):
if n <= 1:
return 0
elif n % 2 == 0:
return n - 1 + f_recursive1(n-2)
else: # n odd
return n - 2 + f_recursive1(n-2)
However, this does more work than is strictly necessary, since subtracting 2 from n will never change its parity; you don't need to check n is even or odd in every recursive call.
def f_recursive2(n):
def f_helper(x):
if x <= 0:
return 0
return x + f_helper(x-2)
if n % 2 == 0:
return f_helper(n-1)
else:
return f_helper(n-2)
If we are allowed multiplication and division, I hope you realise that this particular task does not require more than just a base case.
Python code:
def f(n):
total=0
for i in range(1,n,2):
total += i
return total
def g(n):
half = n // 2
return half * half
for n in xrange(100):
print f(n), g(n)
Since
*
* * *
* * * * *
* * * * * * *
can be seen as nested, folded rows. Here are the top two folded rows:
*
* * *
* * * *
* * * *
Let's rotate counterclockwise 45 degrees
* * * *
* * * *
* *
* *
and add the other two folded rows,
*
* *
* * * *
* * * *
* * * *
* * *
and
*
to get
* * * *
* * * *
* * * *
* * * *
the area of a square.
so I've been trying to create a program where you prompt the user for the number of rows, and then the program prints out a diamond with input number of rows.
This is what the program is supposed to do:(image)
This is what my code looks like
def main():
ROWS = get_input()
draw_pattern(ROWS)
def get_input():
return int(input("Enter the number of rows (or -1 or -99 to quit): "))
def draw_pattern(ROWS):
if ROWS == -1 or ROWS == -99:
quit
else:
for x in range(0,(int)((ROWS/2)+1),1):
print ((int)((ROWS/2)-(2*x+1)/2)*" " + (2*x+1) * '*')
for t in range((int)(x),0,-1):
print((int)((ROWS/2)-(2*t-1)/2)*" " + (2*t-1) * '*')
main()
This is what it ends up doing:
Enter the number of rows (or -1 or -99 to quit): 7
*
***
*
*****
***
*
*******
*****
***
*
So what am I doing wrong? I assume it's something in my for loop that makes the rows not line up correctly. Can anyone give me a little help? Thanks.
I got it to work like this. (< 3 mins) (DO NOT use even numbers its going to look odd)
def main():
ROWS = get_input()
draw_pattern(ROWS)
def get_input():
return int(input("Enter the number of rows (or -1 or -99 to quit): "))
def draw_pattern(ROWS):
if ROWS == -1 or ROWS == -99:
return
else:
for x in range(1, ROWS, 2):
print(' ' * int(ROWS / 2.0 - x / 2.0) + ("*" * x))
for x in range(ROWS, 1, -2):
print(' ' * int(ROWS / 2.0 - x / 2.0) + ("*" * x))
if x != 1:
print(' ' * int(ROWS / 2.0 - 1 / 2.0) + ("*" * 1))
main()
There are many ways to do this, you can generate all the strings then print them out using formatting to center the diamond, e.g.:
>>> row = 5
>>> d = ('*' * (n if n <= row else 2*row-n) for n in range(1, 2*row, 2))
>>> for i in d:
... print('{:^{w}}'.format(i, w=row))
*
***
*****
***
*
For row = 4:
*
***
***
*
Points for obfuscation?
star = lambda rows:'\n'.join(('*'*(2*(i if i<rows//2 else rows-i-1)+1)).center(rows) for i in range(rows))
Odd
print(star(5))
*
***
*****
***
*
Even
print(star(4))
*
***
***
*
In Python, I'd like to print a diamond shape of asterisks *:
with $ at the top half of the diamond (upper pyramid) where there isn't a *, and
with & at the bottom half of the diamond (lower pyramid) where there isn't a *.
So far, I only know how to make a pyramid that is right side up:
def pyramid(n):
for i in range(n):
row = '*'*(2*i+1)
print(row.center(2*n))
For example, if the function called was print shape(7), then it would print [this image].
Any ideas?
def shape(n):
for i in range(2*n+ 1):
if (i < n):
print "$" * (n - i) + "*" * 2 * i + "$" * (n - i)
elif i == n:
print "*" * 2 * n
elif i > n:
print "&" * (i - n) + "*" * 2 * (2* n - i) + "&" * (i - n)
I'm trying to figure out how to turn my whole square into a hollow one. The few things I've tried so far haven't been very successful as I end up getting presented with a rather distorted triangle!
This is the code I have to form my square currently ..
size = 5
for i in range(size):
print ('*' * size)
When run, this is the result ..
*****
*****
*****
*****
*****
Do I need to run if or while statements when size is greater than 3 to specify a condition?
I think this is what you want to do:
m, n = 10, 10
for i in range(m):
for j in range(n):
print('*' if i in [0, n-1] or j in [0, m-1] else ' ', end='')
print()
Output:
**********
* *
* *
* *
* *
* *
* *
* *
* *
**********
You can also draw a triangle this way:
m, n = 10, 10
for i in range(m):
for j in range(n):
print('*' if i in [j, m-1] or j == 0 else ' ', end='')
print()
Output:
*
**
* *
* *
* *
* *
* *
* *
* *
**********
You can print out a single '*', followed by size-2 spaces, then a single '*'. This will give you the "hollow" portion. The first and last lines need the full length:
size = 5
inner_size = size - 2
print ('*' * size)
for i in range(inner_size):
print ('*' + ' ' * inner_size + '*')
print ('*' * size)
Here is my python code for drawing a square by entered size N.
n = int(input())
print('*' * n)
for i in range(n-2):
print ('*' + ' ' * (n-2) + '*')
print('*' * n)
Basically the first and the last print('*' * n) are drawing the top and the bottom lines and the for cycle prints the body.
Output example: N=3
***
* *
***
Output example: N=5
*****
* *
* *
* *
*****
Try this:
size = 5
for i in range(1,size+1):
if (i==1 or i==size):
print("*"*size)
else:
print("*"+" "*(size-2),end="")
print("*")
output:
*****
* *
* *
* *
*****
Heres my example:
print("Enter width")
width = int(input())
print("Enter height")
height = int(input())
for i in range(height):
if i in[0]:
print("* "*(width))
elif i in[(height-1)]:
print("* "*(width))
else:
print("*"+" "*(width-2)+" *")
input()
Output: Image link
Hope this helps everyone else, who wants to leave spaces between asteriks, while printing a rectangle and if there are any mistakes in my code let me know, because I'm a beginner myself.
size = int(input('Enter the size of square you want to print = '))
for i in range(size): # This defines the rows
for j in range(size): # This defines the columns
print('*' , end=' ') # Printing * and " end=' ' " is giving space after every * preventing from changing line
print() # Giving a command to change row after every column in a row is done
print() # Leaving one line
for k in range(size): # This defines the rows
print('* ' *size) # Defines how many times * should be multiplied
Here is my python 3.6 code for drawing a square using column size and row size inputs:
column = int(input("Enter column size : "))
row = int(input("Enter row size : "))
print('* ' * column)
print(('* ' + " " * (column-2)+ '*'+'\n')*(row -2) + ('* ' * column))
You can also draw a triangle using this simple way:
n = int(input("enter num"))
for i in range (n+1):
if 2>=i :
print (i * "*")
elif n == i:
print ("*" * i)
else:
print ("*"+" "*(i-2)+"*")
Nice python library that will do this...
termshape - https://github.com/zvibazak/termshape
from termshape import get_rectangle
print(get_rectangle(10, 5))
* * * * * * * * * *
* *
* *
* *
* * * * * * * * * *
In this code, there are 2 for loops and this loops will create edges. And "else statements" represents if our point is not on the edge code will print empty character(" "). "i == 0" shows upper edge and "i == length - 1" shows bottom edge. "j == 0" will be left edge and I think you can guess what is for "j == length - 1" and "print()".
def emptySquare(length,char):
for i in range(length):
for j in range(length):
if (i == 0 or i == length-1 or j == 0 or j == length-1):
print(char,end=" ")
else:
print(" ",end=" ")
print()