I'm currently learning python so I apologize in advance for the messiness of my code. My function is meant to take in a single string and add the string numbers together. i.e. A string argument of 123 will become 1 + 2 + 3 and return 6.
My issue is when I iterate through my list - python keeps indicating that the variable has been referenced before any value has been assigned. However when I print out the values being calculated they are correct. Even more confusing is that when I return them - they are incorrect. I can't seem to work out where I'm going wrong. Could anyone tell me what the issue may be?
Thank you!
listy = []
global total
#Convert number to a list then cycle through the list manually via elements and add them all up
def digit_sum(x):
number= []
number.append(x)
print number
for i in range(len(number)):
result = str(number[i])
print result
#Now it has been converted to a string so we should be able to
#read each number separately now and re-convert them to integers
for i in result:
listy.append(i)
print listy
#listy is printing [5,3,4]
for i in listy:
total += int(i)
return total
print digit_sum(x)
I'm not really sure what's going on in your code there, especially with the messed up indentation, but your problem is easily sovled:
sum(map(int, str(534)))
It makes the number a string, then converts each digit to an int with map, then just sums it all.
If your concern is only about summing a string of numbers, then list comprehension itself would do or as #Maltysen suggested you could use map
sum([int(x) for x in "534"])
pretty simple:
You can use a map or a list comprehension. They are pretty much equivalent. Other people gave an answer using map but I decided to use a list comprehension.
s = "1234567"
sum([int(character) for character in s])
I believe I have worked out what was wrong with my code. As I am still new to Python, I made some very novice mistakes such as not realizing declaring a variable outside the local function would result in the solution not being what I had expected.
Due to my returns being placed incorrectly as well as my listy [] variable being instantiated outside my function, instead of reading each number once, it would read it three times.
This has now been corrected in the code below.
#Convert number to a list then cycle through the list manually via elements and add them all up
def digit_sum(x):
total = 0
number= []
number.append(x)
print number
for i in range(len(number)):
result = str(number[i])
print result
#Now it has been converted to a string so we should be able to
#read each number separately now and re-convert them to integers
for i in result:
listy = []
listy.append(i)
# print listy
#listy is printing [5,3,4]
for i in listy:
print i
total+= int(i)
print total
break
return total
print digit_sum(111)
Related
Link to question: https://www.spoj.com/UTPEST22/problems/UTP_Q2/
From what I understand, the question is divided into 2 parts:
Input
The first input is an integer that limits the number of time the user can provide a set of integers.
From the second line onwards, the user provides the sequence of integers up until the specified limit.
The set of integers are arranged in ascending order, separated only by a space each.
Output
For each sequence of integers, the integers in it are looped over. Only those that are even are printed as outputs horizontally.
from sys import stdin
for x in range(1, 1+ int(input())):
# number of cases, number of times the user is allowed to provide input
for line in stdin:
num_list = line.split()
# remove the space in between the integers
num = [eval(i) for i in num_list]
# change the list of numbers into integers each
for numbers in range(num[0], num[-1] + 1):
# the first integer is the lower bound
# the second the upper bound
if numbers % 2 == 0:
# modulo operation to check whether are the integers fully divisible
print(numbers, end = ' ')
# print only the even numbers, horizantally
Can anyone please provide some insights on how to make changes to my code, specifically the loop. I felt so messed up with it. Screenshot of the result.
Any help will be appreciated.
You can use restructure the code into the following steps:
Read each case. You can use the input function here. A list comprehension can be used to read each line, split it into the lower and upper bound and then convert these to integers.
Process each case. Use the lower and upper bounds to display the even numbers in that range.
Using loops: Here is an example solution that is similar to your attempt:
n = int(input())
cases = []
for case in range(n):
cases.append([int(x) for x in input().split()])
for case in cases:
for val in range(case[0], case[1] + 1):
if val % 2 == 0:
print(val, end=' ')
print()
This will produce the following desired output:
4 6 8 10 12 14 16 18 20
2 4 6 8 10 12 14 16
-4 -2 0 2 4 6
100 102 104 106 108
Simplify using unpacking: You can simplify this further by unpacking range. You can learn more about unpacking here.
n = int(input())
cases = []
for case in range(n):
cases.append([int(x) for x in input().split()])
for case in cases:
lower = case[0] if case[0] % 2 == 0 else case[0]
print(*range(lower, case[1] + 1, 2))
Simplify using bit-wise operators: You can simplify this further using the bit-wise & operator. You can learn more about this operator here.
n = int(input())
cases = []
for case in range(n):
cases.append([int(x) for x in input().split()])
for case in cases:
print(*range(case[0] + (case[0] & 1), case[1] + 1, 2))
So first of obviously ask user to input the range however many times they specified, you can just split the input and then just get the first and second item of that list that split will return, by using tuple unpacking, then append to the ranges list the range user inputted but as a Python range object so that you can later easier iterate over it.
After everything's inputted, iterate over that ranges list and then over each range and only print out the even numbers, then call print again to move to a new line in console and done.
ranges = []
for _ in range(int(input())):
start, end = input().split()
ranges.append(range(int(start), int(end) + 1))
for r in ranges:
for number in r:
if number % 2 == 0:
print(number, end="")
print()
Here's my solution:
n = int(input())
my_list = []
for i in range(n):
new_line = input().split()
new_line = [int(x) for x in new_line]
my_list.append(new_line)
for i in my_list:
new_string = ""
for j in range(i[0], i[1]+1):
if (not(j % 2)): new_string += f"{j} "
print(new_string)
Read the first value from stdin using input(). Convert to an integer and create a for loop based on that value.
Read a line from stdin using input(). Assumption is that there will be two whitespace delimited tokens per line each of which represents an integer.
Which gives us:
N = int(input()) # number of inputs
for _ in range(N):
line = input()
lo, hi = map(int, line.split())
print(*range(lo+(lo&1), hi+1, 2))
There are a few issues here but I'm guessing this is what's happening: you run the code, you enter the first two lines of input (4, followed by 3 20) and the code doesn't print anything so you press Enter again and then you get the results printed, but you also get the error.
Here is what's actually happening:
You enter the input and the program prints everything as you expect but, you can't see it. Because for some reason when you use sys.stdin then print without a new line, stdout does not flush. I found this similar issue with this (Doing print("Enter text: ", end="") sys.stdin.readline() does not work properly in Python-3).
Then when you hit Enter again, you're basically sending your program a new input line which contains nothing (equivalent to string of ""). Then you try to split that string which is fine (it will just give you an empty list) and then try to get the first element of that list by calling num[0] but there are no elements in the list so it raises the error you see.
So you can fix that issue by changing your print statement to print(numbers, end = ' ', flush=True). This will force Python to show you what you have printed in terminal. If you still try to Enter and send more empty lines, however, you will still get the same error. You can fix that by putting an if inside your for loop and check if line == "" then do nothing.
There is still an issue with your program though. You are not printing new lines after each line of output. You print all of the numbers then you should go to the newline and print the answer for the next line of input. That can be fixed by putting a print() outside the for loop for numbers in range(num[0], num[-1] + 1):.
That brings us to the more important part of this answer: how could you have figured this out by yourself? Here's how:
Put logs in your code. This is especially important when solving this type of problems on SPOJ, Codeforces, etc. So when your program is doing that weird thing, the first thing you should do is to print your variables before the line of the error to see what their value is. That would probably give you a clue. Equally important: when your program didn't show you your output and you pressed Enter again out of confusion, you should've gotten curious about why it didn't print it. Because according to your program logic it should have; so there already was a problem there.
And finally some side notes:
I wouldn't use eval like that. What you want there is int not eval and it's just by accident that it's working in the same way.
We usually put comments above the line not below.
Since it appears you're doing competitive programming, I would suggest using input() and print() instead of stdin and stdout to avoid the confusions like this one.
SPOJ and other competitive programming websites read your stdout completely independent of the output. That means, if you forget to put that empty print() statement and don't print new lines, your program would look fine in your terminal because you would press Enter before giving the next input line but in reality, you are sending the new line to the stdin and SPOJ will only read stdout section, which does not have a new line. I would suggest actually submitting this code without the new line to see what I mean, then add the new line.
In my opinion, the variable numbers does not have a good name in your code. numbers imply a list of values but it's only holding one number.
Your first if does not need to start from 1 and go to the number does it? It only needs to iterate that many times so you may as well save yourself some code and write range(int(input())).
In the same for loop, you don't really care about the value of variable x - it's just a counter. A standard practice in these situations is that you put _ as your variable. That will imply that the value of this variable doesn't really matter, it's just a counter. So it would look like this: for _ in range(int(input())).
I know some of these are really extra to what you asked for, but I figured you're learning programming and trying to compete in contests so thought give some more suggestions. I hope it helped.
Steps for simple solution
# taking input (number of rows) inside outer loop
# l = lower limit, u = upper limit, taking from user, then converting into integer using map function
# applying logic for even number
# finally printing the even number in single line
for j in range(int(input())):
l, u = map(int, input('lower limit , upper limit').split())
for i in range(l, u+1):
if i%2 == 0: # logic for even number
print(i, end=' ')
I am trying to create a golf calculator in which I enter two strings (par_string,score_string). For each item in par_string and score_string, I subtract the score_string item from the par_string item.
I have tried turning the strings into integers but it still doesn't work.
#score_string-par_string
def golf_score_calculator(par_string, score_string):
new_str = ""
par = int(par_string,10)
score = int(score_string,10)
for i in str(par):
for i in str(score):
new_str += score_string[i]-par_string[i]
return new_str
print(golf_score_calculator("12","13"))
What should happen is that each time a value is subtracted, it adds on to new_str.
I think that the problem is bacause you are using the same index for two nested loops.
Well it is odd you are using strings instead of lists of ints but if you have two strings and you want the difference, simply doing
def golf_score_calculator(par_string, score_string):
return str(int(par_string) - int(score_string))
should be what you want.
I am currently a beginner in Python. This is my problem: First, the program asks that you input a number.
For example, if I put 1, I get 1 out. If i put 2, i get 12 out. If I put 3, I get 123. If I put 4, I get 1234. That is the gist of this set of problem. However, I developed a mathematical equation that works if I put it through a loop:
if __name__ == '__main__': # ignore this part
n = int(input())
s = 1
while s > n:
z = s*10**(n-s)
s += 1
answer = z
if s == n:
print(z)
When I tried to run this code, I got nothing, even though I added print at the end. What is it that I am doing wrong here? For anyone answering the problem, introduce any concepts that you know that may help me; I want to learn it.
Please enlighten me. Don't exactly give me the answer....but try to lead me in the right direction. If I made a mistake in the code (which I am 100% sure I did), please explain to me what's wrong.
It's because your while loop condition is backwards. It never enters the loop because s is not bigger than n. It should be while s < n
Use a for loop using range() as in
for i in range(1, n+1):
where n is the input so that the numbers from 1 till n can be obtained.
Now use a print() to print the value of i during each iteration.
print() by default will add a newline at the end. To avoid this, use end argument like
print(var, end='')
Once you are familiar with this, you can also use list comprehension and join() to get the output with a single statement like
print( ''.join([str(i) for i in range(1, n+1)]) )
Take the input as you've done using input() and int() although you might want to include exception handling in case the input is not an integer.
See Error handling using integers as input.
Here is the solution:
Using string
a = int(input())
# taking the input from the user
res=''
# using empty string easy to append
for i in range(1,a+1):
# taking the range from 1 (as user haven't said he want 0, go up to
# a+1 number (because range function work inclusively and will iterate over
# a-1 number, but we also need a in final output ))
res+=str(i)
# ^ appending the value of I to the string variable so for watch iteration
# number come append to it.
# Example : 1-> 12-> 123-> 1234-> 12345-> 123456-> 1234567-> 12345678-> 123456789
# so after each iteration number added to it ,in example i have taken a=9
sol = int(res) #converting the res value(string) to int value (as we desire)
print(sol)
In one line, the solution is
a=int(input())
res=int(''.join([str(i) for i in range(1,a+1)]))
Try this,
n = int(input('Please enter an integer'))
s = 1
do:
print(s)
s+=1
while s == n
this works.
(Simple and Short)
So, basically i want to know why this piece of code works at times... Sometimes it works just fine, and sometimes it brings that index error. I have a bidimensional list 4x100 with data. Im simply retrieving data from the third row to sum it all in 1 variable.
Here is the list:
a=4
lst = [[] for _ in xrange(a)]
wifi= Wireless('wlan0')
while i<100:
results = wifi.scan()
print cont
print "%-8.16s Scan completed :" % (wifi.ifname,)
for ap in results:
if ap.bssid==AP1:
lst[0].append(ap.quality.getSignallevel())
if ap.bssid==AP2:
lst[1].append(ap.quality.getSignallevel())
if ap.bssid==AP3:
lst[2].append(ap.quality.getSignallevel())
if ap.bssid==AP4:
lst[3].append(ap.quality.getSignallevel())
i=i+1
cont=cont+1
for j4 in range(0,100):
num7=num7+lst[3][j4]
As it has already been mentioned there is not enough information to tell you exactly why you have the index out of range error.
There are several possible reasons:
wifi.scan() does not return exactly 4 values in a list. This why the third list in lst is not of size 100. Just check the results list has exactly 4 values.
Not all if statements work due to some reason. You need to check the values of each ap item - just print them out and read through the values. The the constants AP1, AP2 etc - are they initialized properly?
Also I would use elif statements instead of just if. I think it will make the code more readable and nice.
I want function to take the last digit of each number in the list and sum them up all together. So forexample, the function below would return "10".
def getSumOfLastDigits(numList):
x = sum(int(num[-1:]) for num in numList)
print x
getSumOfLastDigits([1, 23, 456])
>>>10
Here is what i receive instead of the expected out "10"
def getSumOfLastDigits(numList):
x = sum(int(num[-1:]) for num in numList)
print x
getSumOfLastDigits([1, 23, 456])
Too much work.
def getSumOfLastDigits(numList):
return sum(x % 10 for x in numList)
x = sum(num%10 for num in numList)
You can't index into a number; a number isn't a sequence of digits (internally, it isn't represented in base 10). You can obtain the last digit of a number using mathematical manipulation instead: take the remainder when dividing by 10. We do this with the % operator.
Also:
Don't print the value in your function, return it. Let the calling code decide what to do with the value. Calculation and output are separate tasks, and should be kept separate.
Avoid indicating data types in variable names - yes, even in Python. It's not a good idea to build in assumptions that aren't actually necessary. You could use any kind of sequence here, for example. The simplest way to indicate that you have more than one number is to use the plural, numbers. That also means you use a full word, and people don't have to think about what 'num' is short for.
There is no need to assign the result of an expression to a temporary variable, if you are just going to use it once, and right away. The name x doesn't tell us anything, so cut it out.
get is considered an ugly prefix for function names by most Pythonistas. It should already be obvious that the function calculates and returns a value. Use noun-type names for those functions, and verb-type names for functions that are primarily intended to manipulate some existing data.
Thus:
def sum_of_last_digits(numbers):
return sum(number % 10 for number in numbers)
def getSumOfLastDigits(numList):
total=0
for item in numList:
newItem=str(item)
length=newItem[len(newItem)-1]
total+=int(length)
return total