Python 3 - Christmas tree code - syntax errors - python

I'm very new to coding and I'm trying (and failing) to make a code that prints a Christmas-tree shape of "*" in whatever size instructed, and don't know where I'm going wrong, but I keep getting a variety of syntax errors all over my code.
size_raw = input("Size of tree?")
def spaces(length, size):
Space = " "
new_len = size / 2
new_len -= length
space_s = int(Space) * int(new_len)
return space_s
def segment(h, tw, bw, s):
line = tw
star = "*"
while line <= bw:
stars = line * star
print (spaces(int(line), int(s)) + (stars) + (spaces(int(line), int(s))
line += 2
def tree(size):
Topwidth = 1
height = 3
while Topwidth <= size:
bottom_width = Topwidth + height
segment(int(height), int(Topwidth), int(bottom_width), int(size)
height += 2
if size_raw == "Very Big":
tree(100)
elif size_raw == "Massive":
tree(1000)
else:
tree(int(size_raw))
I expect it to work smoothly in this current state, however it responds with an error of a new for in a new location with each new attempt.

Your parenthesis are not closed properly.
Your code
print (spaces(int(line), int(s)) + (stars) + (spaces(int(line), int(s))
segment(int(height), int(Topwidth), int(bottom_width), int(size)
My version
print (spaces(int(line), int(s))) + (stars) + (spaces(int(line), int(s)))
segment(int(height), int(Topwidth), int(bottom_width), int(size))
Got it to work with this fiddle, where i also change the indention to be with 4 spaces which is the most common indention.

Related

Unable to find the minimum number of vertical and horizontal cuts due to the following error

I am writing a code to find the minimum number of horizontal and vertical cuts to form a square. I am generating 'cannot unpack non-iterable NoneType object' error, does this have anything to do with the functools package? If not, what changes can I make otherwise?
import functools
#functools.lru_cache
def get_C(height, width):
if height == width:
return("",0)
cold = height*width
for tryleftlen in range(1, width//2+1):
leftcuts, leftminimum = get_C(height, tryleftlen)
rightcuts, rightminimum = get_C(height, width-tryleftlen)
ctry = 1+leftminimum +rightminimum
if ctry < cold:
minimumcut = 'V{0}x{1} --> {0}x{2} {0}x{3}\n'.format(height,width,tryleftlen,width-tryleftlen)
minimumcut += leftcuts + rightcuts
cold = ctry
for trybotlength in range(1, height//2+1):
topcuts, topminimum = get_C(height-trybotlength, width)
botcuts, botminimum = get_C(trybotlength, width)
ctry = 1+ botminimum + topminimum
if ctry < cold:
minimumcut = 'H{0}x{1}-->{2}x{1} {3}x{1}\n'.format(height,width,trybotlength.height-trybotlength)
minimumcut += botcuts + topcuts
cold = ctry
return (minimumcut, cold)
if __name__ == '__main__':
C = get_C(6,7)
C = get_C(12,13)
print(C[0])
oops, it was a small syntax error and nothing to do with import functools.
at this line:
minimumcut = 'H {0}x{1} --> {2}x{1} {3}x{1}\n'.format(height,width,trybotlength,height-trybotlength)
Thank you.

Python Convert Inches and Feet into Inches

I am trying to convert arrays that contain both Inches and Feet into Inches. The feet are denoted with a single quote (') and inches are denoted with double quotes ("). The data comes in the following forms:
[8'x10']
[60\" x 72\"]
[5'x8',5x8,60\"x92\"]
[8'10\"x12']
What I want:
["96x120"]
["60x72"]
["60x96","60x96","60x96","60x92"]
["106x144"]
What I have:
def ft_inch(numbers):
if str(numbers).find("x") > -1:
numbers=numbers.replace('[','').replace('"','').replace('[','').replace(']','')
try:
nom = numbers.split("x")[0]
nom=nom.replace(r'\\|\"|\]|\[','')
nom_one = nom.split("'")[0]
nom_two = nom.split("'")[1]
den = numbers.split("x")[1]
den=den.replace(r'\\|\"|\[|\]','')
den_one = den.split("'")[0]
den_two = den.split("'")[1]
ft=int(nom_one)*12
inch=nom_two.replace(r'\"| |\\','')
try:
inch=int(inch)
except:
print('B')
tmp = int(ft)+int(inch)
fts=int(den_one)*12
inchs=den_two.replace(r'\"| |\\','')
try:
inchs=int(inchs)
except:
print('B')
tmp_two = int(fts)+int(inch)
return f'["{tmp}x{tmp_two}"]'
except:
return numbers
else:
return numbers
x="[5'1x8'1]"
ft_inch(x)
This works for a single array as long as it has both feet and inches but fails if its only feet [8'x8']. If anyone has a simpler solution please let me know
A regex-based approach:
import re
inputs = [["8'1x10'1"], ["60\" x 72\""], ["5'x8'", "5x8", "60\"x92\""], ["8'10\"x12'"]]
for inpt in inputs:
sub_output = []
for measurement in inpt:
m = re.match(r"(\d+['\"]?)(\d+['\"]?)?x(\d+['\"]?)(\d+['\"]?)?",
"".join(measurement.split()))
groups = [m.groups()[:2], m.groups()[2:]]
result_inches = [0, 0]
for i, group in enumerate(groups):
for raw_val in group:
if raw_val == None:
continue
if '"' in raw_val:
result_inches[i] += int(raw_val[:-1])
elif "'" in raw_val:
result_inches[i] += int(raw_val[:-1])*12
else:
result_inches[i] += int(raw_val)*12
sub_output.append(result_inches)
print([f"{x}x{y}" for x, y in sub_output])
Output:
['108x132']
['60x72']
['60x96', '60x96', '60x92']
['106x144']
I saw your edit and included the ["8'1x10'1"] case :)
I rewrote the entire thing, but this seems to work:
input_ = ["8'x10'", "60\" x 72\"", "5'x8'","5x8","60\"x92\"", "8'10\"x12'", "8'1x10'1\""]
inches_only = []
for s in input_:
s.replace(" ", "")
sides = s.split("x")
new_sides = []
for side in sides:
inches = 0
split1 = side.split("'")
if len(split1) > 1 or (len(split1) == 1 and not side.__contains__('"')):
inches = int(split1[0]) * 12
split2 = side.split('"')
if len(split2) > 1:
inches += int(split2[0].split("'")[-1])
elif len(split2) == 1 and len(split1) > 1 and len(split1[1]) > 0:
inches += int(split1[1])
new_sides.append(str(inches) + '"')
inches_only.append("x".join(new_sides))
print(inches_only)
Output:
['96"x120"', '60"x72"', '60"x96"', '60"x96"', '60"x92"', '106"x144"', '97"x121"']

Working code but pycharm marks tmF and tmR in list as "local variable referenced before assignment", why is this?

I've only recently started programming so there may be a simple answer to this question but I couldn't find it on here. My code works fine for what I want to do but as I am new to this I want to get into the practice of writing good readable code. I am using PyCharm and I noticed it marked some of the code below as not defined. I understand a little about global vs local variables and I guess it has something to do with this but I can't work out why this part of the code works at all if this is the case.
if len(primerF) < 14:
tmF = (no_A_F + no_T_F) * 2 + (no_C_F + no_G_F) * 4
float_tmF = float(tmF)
print("Forward primer tm: " + str(float_tmF))
elif len(primerR) > 13:
tmR = 64.9 + 41*(no_C_R + no_G_R - 16.4) / (no_A_R + no_T_R + no_G_R +
no_C_R)
print("Reverse primer tm: " + str(tmR))
if len(primerR) < 14:
tmR = (no_A_R + no_T_R) * 2 + (no_C_R + no_G_R) * 4
print("Reverse primer tm: " + str(tmR))
elif len(primerR) > 13:
tmR = 64.9 + 41*(no_C_R + no_G_R - 16.4) / (no_A_R + no_T_R + no_G_R +
no_C_R)
print("Reverse primer tm: " + str(tmR))
gc_F = (no_G_F + no_C_F)
gc_content_F = float(gc_F) / forward_length * 100
print("Forward GC content: " + str(gc_content_F) + "%")
gc__R = (no_G_R + no_C_R)
gc_content_R = float(gc__R) / reverse_length * 100
print("Reverse GC content: " + str(gc_content_R) + "%")
This block here is marked as name not defined and if I click on the bubble it says: "This inspection warns about local variables referenced before assignment".
list_tm = [**tmF**, **tmR**]
high_tm = max(list_tm)
low_tm = min(list_tm)
You're setting tmF and tmR in conditional blocks that do not cover all possibilities. For example, if primerF is >= 14, tmF will never be set before the list_tm = [tmF, tmR] statement. This will result in a runtime error, which pycharm is warning you about.
One way to fix this is to set default values of tmF and tmR at the top of your code, or to have full conditional coverage by setting tmF and tmR in else (not just elif) blocks.

PyParsing: Parsing Cisco's "show ip bgp"

I am trying to parse a string as below using PyParsing.
R1# show ip bgp
BGP table version is 2, local router ID is 1.1.1.1
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
r RIB-failure, S Stale
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
> 10.1.1.0/24 192.168.1.2 0 0 200 i
Note that LocPrf value is empty but it can be a number.
ipField = Word(nums, max=3)
ipAddr = Combine(ipField + "." + ipField + "." + ipField + "." + ipField)
status_code = Combine(Optional(oneOf("s d h * r")) + ">" + Optional(Literal("i"))
prefix = Combine(ipAddr + Optional(Literal("/") + Word(nums,max=2)))
next_hop = ipAddr
med = Word(nums)
local_pref = Word(nums) | White()
path = Group(OneOrMore(Word(nums)))
origin = oneOf("i e ?")
This is the grammar.
g = status_code + prefix + next_hop + med + local_pref + Suppress(Word(nums)) + Optional(path) + origin
I just need to parse the Bold line. But this is not parsing it properly. It assigns Weight value to LocPrf.
Please look over the following code example (which I will include in the next pyparsing release). You should be able to adapt it to your application:
from pyparsing import col,Word,Optional,alphas,nums,ParseException
table = """\
12345678901234567890
COLOR S M L
RED 10 2 2
BLUE 5 10
GREEN 3 5
PURPLE 8"""
# function to create column-specific parse actions
def mustMatchCols(startloc,endloc):
def pa(s,l,t):
if not startloc <= col(l,s) <= endloc:
raise ParseException(s,l,"text not in expected columns")
return pa
# helper to define values in a space-delimited table
def tableValue(expr, colstart, colend):
return Optional(expr.copy().addParseAction(mustMatchCols(colstart,colend)))
# define the grammar for this simple table
colorname = Word(alphas)
integer = Word(nums).setParseAction(lambda t: int(t[0])).setName("integer")
row = (colorname("name") +
tableValue(integer, 11, 12)("S") +
tableValue(integer, 15, 16)("M") +
tableValue(integer, 19, 20)("L"))
# parse the sample text - skip over the header and counter lines
for line in table.splitlines()[2:]:
print
print line
print row.parseString(line).dump()

Maya Variable Concatenation

Having a few problems basically inserting a bunch of flags generated by a loop:
def drawHelix(radius, length, coils):
numPoints = int(8)
degrees = float((360 / numPoints))
centerX = float(0)
centerZ = float(0)
xLoc = float(0)
zLoc = float(0)
yLoc = float(0)
yOffset = float(((length / coils) / numPoints))
vectorIndex = int(0)
pointStr = ""
knotStr = ""
for i in range(1, (360 * coils), 20):
t = i + degrees
xLoc = centerX + (math.cos(t) * radius)
zLoc = centerZ - (math.sin(t) * radius)
pointStr = (pointStr + " p=(" + str(xLoc) + "," + str(yLoc) + "," + str(zLoc) + "),")
knotStr = (knotStr + "k=(" + str(vectorIndex) + ")")
vectorIndex = i + 1
yLoc = yLoc + yOffset
print pointStr
spiral = cmds.curve(d=float(1.0), pointStr, knotStr)
cmds.rebuildCurve (spiral, ch=1, rpo=1, rt=0, end=1, kr=1, kcp=0, kep=0, kt=0, s=0, d=3, tol=0.001)
return spiral
Which I then run with: drawHelix (2.00, 3.00, 5.00)
The problem is that Maya doesn't recognise the "pointStr" as a flag for the curve command, when I print pointStr it does give me exactly what I want, but struggling on how to actually make this work!
The Python interpreter will not expand your strings before calling the function (you could achieve this using eval but this is generally considered bad practice -- see this post on SO).
It should work when passing the arguments as a dict of keywords.
Look it up here:
Section 4.7 More on Defining Functions in the Official Python Tutorial
PEP 3102 Keyword-Only Arguments
Section 5.3.4 Calls in the Python Reference Manual
So instead of:
pointStr = (pointStr + " p=(" + str(xLoc) + "," + str(yLoc) + "," + str(zLoc) + "),")
knotStr = (knotStr + "k=(" + str(vectorIndex) + ")")
You should do
kwargs['d'] = 1.0
kwargs['p'] = []
for i in range(1, (360 * coils), 20):
...
kwargs['p'].append((xloc, yloc, zloc))
kwargs['k'].append(vectorIndex)
spiral = cmds.curve(**kwargs)
Apart from that there are a few other issues in your code:
float((360 / numPoints)) will evaluate differently in Python2.x and Python3.x. This is what happens in 2.x:
In [5]: float(7 / 6)
Out[5]: 1.0
In [6]: 7. / 6
Out[6]: 1.1666666666666667
In If you wanted to ensure that floating point division is performed in your case use degrees = 360. / numPoints.
The potential implications are worse in this line of your code: yOffset = float(((length / coils) / numPoints)).
You declare float and int constants just by writing them either with or without a decimal point. No need to wrap them in a call to float() or int()
I assume this is what you had in mind:
from maya import cmds
import math
def drawHelix(radius, length, coils):
numPoints = int(8)
degrees = float((360 / numPoints))
centerX = float(0)
centerZ = float(0)
xLoc = float(0)
zLoc = float(0)
yLoc = float(0)
yOffset = float(((length / float(coils)) / float(numPoints)))
vectorIndex = int(0)
pointStr = []
knotStr = []
yLoc = 0
for i in range(1, (360 * coils), 20):
t = i + degrees
xLoc = centerX + (math.cos(t) * radius)
zLoc = centerZ - (math.sin(t) * radius)
pointStr.append((xLoc, yLoc,zLoc))
knotStr.append(vectorIndex)
vectorIndex = i + 1
yLoc = yLoc + yOffset
print pointStr
spiral = cmds.curve(p= pointStr, k=knotStr,d=float(1.0))
cmds.rebuildCurve (spiral, ch=1, rpo=1,
rt=0, end=1, kr=1, kcp=0, kep=0,
kt=0, s=0, d=3, tol=0.001)
return spiral
There is just a way much better way to do this. This is how your supposed to use Maya, use nodes to build your stuff. So here goes, a unnecessarily commented and verbose version:
from maya import cmds
def getHistoryShape(name):
history = cmds.listHistory(name)
filteredShape = cmds.ls(history, shapes=1)[0]
return filteredShape
def drawHelix(radius, length, coils):
cyl = cmds.cylinder( ch=True, radius=radius, ax=(0,1,0),
hr=float(length)/float(radius) )
# build a curve on the cylinders surface
crv = cmds.curveOnSurface(cyl[0], d=1,
uv=[(0,0),(length, coils*4)],
k=[0,1])
# make a duplicate that is visible
crv = cmds.duplicateCurve(ch=1, rn=0, local=1)
# tell maya to ignore the cylinder as a piece of geometry
shape = getHistoryShape(cyl[0])
cmds.setAttr(shape+'.intermediateObject', 1)
cmds.rename(cyl[0],'helix1')
return crv
Now you can change the helixes parameters later, live. You could expose the parameters radius, length and coils for the user, so they can be animated. See Maya factory scripts for example.

Categories