SyntaxError: can't assign to function call Python 3.3 - python

I would like to know what SyntaxError: can't assign to function call (<string>, line 6) means in relation to my specific line of code. I've looked around just about everywhere and I'm not getting anything I understand, simply because I just started learning code yesterday and much of what everyone else has mixed in with their strings of code is confusing.
Here is what I have entered:
name = 'Hayley'
print(len(name))
while len(name) < 10:
print('k')
len(name) = len(name) + 1
print('Done.')
I want the program to add 1 to the length of the name until it isn't less than ten anymore. It starts off at 6 and then increases by 1 until it hits 10 and the program doesn't run anymore.
I'm just trying to practice with loops and using a lot of meaningless things just to practice and make sure it sticks in my head. I'm trying to learn to code for an internship I will work at this summer.

Better to remember while a beginner,
if there is parantheses(round bracket) in the left side of an assignment, you should check it again and be extra careful.
len("arg")
is a function called with the argument "arg" and it already returns a value. Therefore cannot be assigned to something, something can be assigned to it.
I cannot truly help you because of not knowing exactly what you are trying to do. But what you expected to happen while you tried to increase the length of the string, by using the function to measure the length alone. Study on what you exactly want and you will get closer to the answer, like in all other subjects.

len(name) returns you the length of "Hayley" in your code above. You cannot assign another value to it. Perhaps you meant to do this:
>>> name = "Hayley"
>>> x = len(name)
>>> print(x)
6
In [2]:
>>> while x < 10:
>>> print('k')
>>> x += 1
>>> print('Done.')
k
k
k
k
Done.

Related

I don't understand how this recursive function works

So these are the examples I got:
def bottom_up(n):
if n == 0:
pass
else:
bottom_up(n-1)
print(n)
and this one, which is fine:
def top_down(n):
if n == 0:
pass
else:
print(n)
top_down(n-1)
I have an understanding of recursion, so that isn't the problem. My problem is the result for bottom_down():
bottom_up(5)
1
2
3
4
5
I've asked other students and my teacher(math teacher, because my school won't hire a computer science teacher since I'm the only one doing computer science), and I don't know what to search on google.
I highly encourage you to walk through the functions yourself to see how it works, but the difference is in the order of the print statement and the recursive call.
The first function has the recursive call before the print statement, so that means it has to go down to the base case in order to start printing the numbers. This means it will start at the smallest number and go up and back to the starting number.
The second function has the print statement before the recursive call, which means that it will print the number then take a step closer to the base case. Once the base case is reached, the recursive calls go back up, and exit as there is nothing after them.
Hope this helped.
Pass is a placeholder for code.
Need more context in what you are trying to do.
bottom_up(5) is looping
So before bottom_up(5) prints 5 it will run the function bottom_up(4), bottom_up(3), bottom_up(2), bottom_up(1), bottom_up(0) and so on....
bottom_up(0) and and negative n will pass and not print anything.
So the first thing to print will be bottom_up(1) then bottom_up(2) and so on until 5.

Trying to solve the Biggest Prime Factor problem from Project Euler (Problem 3) through recursion in python

I have been trying to solve Problem #3 in ProjectEuler in python. I have tried using recursion to get factors of my factors. But I keep on running into a recursive limit reached error for some reason. Can anyone help me out as to why its happening?
def getPrimeFactors(y):
AllFactors = [[x, int(y/x)] for x in range(1, (int(math.sqrt(y)+1))) if y%x==0]
Flattened_AF = [j for i in AllFactors for j in i]
print(AllFactors)
print(Flattened_AF)
if len(Flattened_AF)==2:
print(Flattened_AF)
return Flattened_AF
else:
PrimeFactors = [x for x in Flattened_AF if len(getPrimeFactors(x))==2]
print (f'loop in else - {PrimeFactors}')
print(max(PrimeFactors)
getPrimeFactors(4)
This is the problem as quoted in the website.
I am sorry if the code readability quality is a bit low but I had been trying to debug for a long time in vain.
When you define AllFactors for in input y, you iterate from 1, so the same number y is always contained within AllFactors. As such, when you call getPrimeFactors on the input, that same input y is passed, so this becomes an infinite loop.
Iterating from 2 instead of 1 stops the recursion error.
Also, just a tip, typically in python variables names begin with a lower case and classes begin with uppercase. There is more about naming conventions here:https://visualgit.readthedocs.io/en/latest/pages/naming_convention.html.

1 line function to get middle letters, syntax error

Trying to write a one-line function that will take the input string and get the middle letter/letters depending on if the string is even or uneven. I get an error code saying there's a syntax error at the first len(s) after the else if. The third line of code should continue on the second line.
The code:
def get_middle(s):
return m = s[int(len(s/2))] if type(len(s)/2) is float else if
s[int(len(s)/2)-1:int(len(s)/2)]
The ERROR:
Traceback (most recent call last):
File "main.py", line 1, in <module>
from solution import *
File "/home/codewarrior/solution.py", line 2
return m = s[len(s/2)] if type(len(s)/2) is float else if
s[int(len(s)/2)-1:int(len(s)/2)]
^
SyntaxError: invalid syntax
type(len(s)/2) is float is not a check for even-odd length, as you can see below, both even and odd string lengths evaluate to True for the check you had, because both divisions are float values
4/2 = 2.0 and 5/2=2.5
In [16]: s = 'abcd'
In [17]: type(len(s)/2) is float
Out[17]: True
In [18]: s = 'abcde'
In [19]: type(len(s)/2) is float
Out[19]: True
Why not keep things simple by checking divisibility by 2 for even/odd length.
Check if the number is length is odd or even, and select middle characters accordingly.
def get_middle(s):
#If even length, select 2 characters
if len(s)%2 == 0:
return s[int(len(s)/2)-1:int(len(s)/2)+1]
#If odd length, select 1 character
else:
return s[int(len(s)/2)]
print(get_middle('a'))
print(get_middle('ab'))
print(get_middle('abc'))
print(get_middle('abcd'))
print(get_middle('abcde'))
The output will be
a
ab
b
bc
c
From here, we can easily write the one liner
def get_middle(s):
return s[int(len(s)/2)-1:int(len(s)/2)+1] if len(s)%2 == 0 else s[int(len(s)/2)]
The guys in the comments and other answers already answered your question but I want to extend them a bit with some life-style advice. Yes, the issue at hand is that you shouldn't have else if at the end, the correct syntax is foo if condition else bar. And also type(len(s)) is Float is an absurd way to check for oddness. Hopefully, you already got that from the comments.
However, I want to argue that writing things on 1 line just so you can brag about how smart you are is a very detrimental practice. Programs must be written for people to read, and only incidentally for machines to execute. Unless, you can truly make that one liner understandable, it makes no sense to write it like you did - rather prefer to write it on multiple lines to make any errors obvious. Prefer to think about the other people that will be reading this code more than 'oh, see how cool is that'.
Now if you really insist on writing short and concise code, that's ok and here's how you can actually rewrite the thing to be a meaningful one liner:
from math import ceil
def get_middle(s):
return s[ceil(len(s)/2 - 1): ceil(len(s)/2)]
I'll let you figure out why that works on your own.
Your code has syntax error because if cannot be on the second line unless you escape the new line and only expr if cond else expr is valid inline if-statement:
foo() if condition \
else bar()
And there's something you'll probably like: onelinerizer
Original post has another problem with even/odd check. To solve it in one line:
def get_middle(s):
return m = s[int(len(s/2))] if len(s)%2 != 0 else s[int(len(s)/2)-1:int(len(s)/2)]
Here uses %2 to get remainder.
Though comments saying int(len(s)/2) would fail, also it's not guaranteed to be floor of division, as far as I see it's equivalent as len(s)//2:
def get_middle(s):
return m = s[len(s)//2] if len(s)%2 != 0 else s[len(s)//2-1:len(s)//2]

A clean way of closing a reading window capable of analysing strings of variable length in Python?

I'm trying to create a program that can analyze a string sequence. Currently, my program is capable of examining the sequence character by character, but I don't know how to cleanly get it to recognize the end of the string, which will be variable.
str_exp="ABCDAABKLYWAKAT"
n=0
x=5
while n<=10:
window=str_exp[n:x]
print window,
n+=1
x+=1
countA=window.count('A')
print countA
This should output:
ABCDA 2
BCDAA 2
CDAAB 2
DAABK 2
AABKL 2
ABKLY 1
BKLYW 0
KLYWA 1
LYWAK 1
YWAKA 2
WAKAT 2
You just need to change the condition on your while loop to be based on len(str_exp), which will detect the length of the string. I'll leave it up to you to figure out the arithmetic, because you've got all the basic pieces
You can get the length of a string (or many other Python types) with len(s). So, one way to do this is to replace this line:
while n<=10:
with this:
while n<=len(str_exp) - 5:
However, you usually don't want a loop like n = 0 … while n<=bound: … n+=1 in Python; it's better to replace all three lines with just for n in range(bound):. range(5) just means [0, 1, 2, 3, 4], and for n in [0, 1, 2, 3, 4]: means "run this loop with n=0, then with n=1, …, then with n=4", which is exactly what n = 0 … while n<=4: … n+=1 means. So:
for n in range(len(str_exp)-5):
However, either way, it's pretty easy to screw that up and get an off-by-one error, where you either miss the last window, or go too far and pass it. (Fortunately, in Python, that means you'll just print a window with only 4 characters instead of 5, rather than, say, crashing with a segfault.) So, it's often better to think of a way to rewrite your code so you don't need that.
Sometimes, it's easier to think backward than forward. It takes a moment of reflection to make sure that I want to go from 0 to len(str_exp) - 5… but if I define the slices backward, it's obvious to me that I can just go from 5 to len(str_exp). If the same is true for you, you can rewrite it like this:
for n in range(5, len(str_exp)):
window=str_exp[n-5:n]
…
Or, if neither one is obvious, you can define things a different way. For example, if you want to go until the window is not 5 characters long anymore:
for n in range(len(str_exp)):
window=str_exp[n:x]
if len(window) < 5:
break
…
There are even more radical ways to rethink this. To give you an example, you can write a general-purpose window function, and then your loop just looks like this:
for window in iterwindow(str_exp, 5):
…
You probably wouldn't be able to write, or even read, this iterwindow function yet. It looks something like this:
def window(iterable, windowlength):
window = ''
for i in iter(iterable):
if len(window) == windowlength:
window = window[1:]
window = window + i
if len(window) == windowlength:
yield window
But if someone else had written it (in the standard library, or a module you can find on PyPI), you could use it.
Do this:
windowlen = 5
for end in range(windowlen,len(str_exp)):
print str_exp[end-windowlen:end]
Range just creates a list of numbers. By having the last number be the last index in str_exp, and by creating the start of the window with reference to the end, you ensure you never run off the end.
The the range expression into your python shell to see what it does.

Split day-of-month integers into digits, sum them repeatedly until get a single-digit integer

I am attempting to take two-digit integers representing day-of-month, split the digits into single digits by taking each character in the single digit and adding them together to form a new number.
e.g. If the value for day was an integer 29, then the program would turn that into strings and split them into '2' and '9'. The program would then turn 2 and 9 into integers and add them together to equal 11. Since this is still a double digit number, the program would loop and 1 and 1 would be added together and the final value that would print would be 2. According to the code below(mostly the last ~5 lines), if I enter day=29, then the final answer I keep getting is 4 which is incorrect. Can someone help me fix this:
Note someone mentioned that I didn't re-enter dayStringSum and I accidentally deleted their post am not sure what that means at all.
dayString = str(int(day))
# Turns value day into int
dayStringA = int(str(dayString[0]))
# If day=29 then this variable represents the 2...
dayStringB = int(str(dayString[1]))
# ...and this represents the 9
dayStringSum = (dayStringA + dayStringA)
while(dayStringSum >=10):
dayStringA = int(str(dayStringSum[0]))
# Since daystringsum is now 11, this code changes the value of daystringA into a new value of 1, likewise for below.
dayStringB = int(str(dayStringSum[1]))
print(dayStringSum)
dayStringSum is an integer, so dayStringSum[n] makes no sense. You'll want to turn it into a string first, and then look at its individual characters.
Also, you do not assign a new value to dayStringSum inside the while loop, so if it is >= 10 upon entering the loop, it will remain so, resulting in an infinite loop. You say that you got a final result of 4, but I fail to see how you would get a final result at all.
Try something like this:
daySum = int(day) # Ensure that day is an int before we start.
while(daySum >= 10):
newString = str(daySum)
dayIntA = int(newString[0])
dayIntB = int(newString[1])
daySum = dayIntA + dayIntB # Will be checked on next iteration.
print(daySum)
I'm guessing the reason you're getting the wrong answer is that you add dayStringA + dayStringA when you meant to add dayStringA + dayStringB, i.e. it's just a typo.
The other thing you need to fix is that in the loop, you don't change dayStringSum. This hasn't been a problem so far because dayStringSum is less than 10 in your example, so the loop never executes in the first place, but once you fix that typo, you're going to get an infinite loop and the program will never stop.
Here's what I mean: suppose your day is 29. When you get to this line:
while(dayStringSum >=10):
then dayStringSum will be 11. So then you set dayStringA to 1,
dayStringA= int(str(dayStringSum[0]))
and also dayStringB to 1.
dayStringB= int(str(dayStringSum[1]))
Then that's the end of the loop. So Python goes back to this line:
while(dayStringSum >=10):
What's dayStringSum? Why, it's still 11! You never changed it. So Python will keep looping, going through the same logic over and over again.
Now beyond that, there are a bunch of things that make this code way more complicated than it needs to be. I'm not going to go through them (Code Review would be the place for that), but in general, you don't need to convert things to ints if they are already ints, and likewise you don't need to use str on something that is already a string.
try sum(map(int,"265"))
that maps them to ints and sums them ...
>>> sum(map(int,"254"))
11
or
>>> sum(map(int,str(29)))
11
oh well since its homework I cant really just give away the answer ....
but
its similar to
sum1=0
for integer in [1,2,3]: sum1 += integer
print sum1
Easier way is to take modulus 9 of the number
>>> print(29%9)
2
day = 29
while day >= 10:
day = sum(int(digit) for digit in str(day))
(Also, whenever you're doing major manipulations of the individual digits of an integer, decimal.Decimal is useful, in particular its method
Decimal(29).as_tuple().digits which gives you (2, 9)).

Categories