I am completely new to python, and am trying to print some elements of my list. In second print() I am getting error, which is: 'list indices must be integers or slices, not str'.
The output should be The sum of digits operation performs 1+4. Where am I wrong?
def sum_of_digits(s):
letters = []
numbers = []
for i in s:
if i.isalpha():
letters.append(i)
elif i.isdigit():
numbers.append(i)
print("The extracted non-digits are: {} ". format(letters), end="\n")
print("The sum of digits operation performs ", s.join(int(i, numbers[i])))
sum_of_digits("1aw4")
Let's examine s.join(int(i, numbers[i]))
int(a,b) mean convert a as an int with base b, for example
int('11011', 2) # 27
int('11011', 8) # 4617
int('11011', 10) # 11011
and i in your case is the last char of the string, even numbers[i] is not possible (that's where the exception is)
s.join would mean to put the original s string between each value of the given parameter, non-sens too
You may convert to int each char that is a digit, then just use sum
Sum result
def sum_of_digits(s):
letters = []
numbers = []
for i in s:
if i.isalpha():
letters.append(i)
elif i.isdigit():
numbers.append(int(i))
print("The extracted non-digits are: {} ".format(letters), end="\n")
print("The sum of digits operation performs ", sum(numbers))
The extracted non-digits are: ['a', 'w']
The sum of digits operation performs 5
Sum operation
def sum_of_digits(s):
letters = []
numbers = []
for i in s:
if i.isalpha():
letters.append(i)
elif i.isdigit():
numbers.append(i)
print("The extracted non-digits are: {} ".format(letters), end="\n")
print("The sum of digits operation performs ", "+".join(numbers))
The extracted non-digits are: ['a', 'w']
The sum of digits operation performs 1+4
numbers[i] causes that error because i is a string (it's the last character from the for i in s: loop). Since numbers is a list, indexes must be integers, not strings.
The argument to join should just be the list of strings that you want to join. You don't need to call int(), and you don't need to use i.
The join() method should be called on the string that you want to be the delimiter between each of the elements when they're joined. If you just want to concatenate all the elements, use an empty string, not s.
print("The sum of digits operation performs ", "".join(numbers))
This prints:
The sum of digits operation performs 14
DEMO
Related
Below is the script printing the converted octal to string. I would appreciate suggestion on how to add the - separator to the string on each permission (r/w/x)
def octal_to_string(octal):
result = ""
value_letters = [(4,"r"),(2,"w"),(1,"x")]
#Iterating over each digit in octal
for digit in [int(n) for n in str(octal)]:
#Checking for each of permission values
for value, letter in value_letters:
if digit >= value:
result += letter
digit -= value
else:
pass
return result
I currently get:
In [7]: octal_to_string(755)
Out[7]: 'rwxrxrx'
In [8]: octal_to_string(644)
Out[8]: 'rwrr'
Change the pass to result += "-":
def octal_to_string(octal):
result = ""
value_letters = [(4,"r"),(2,"w"),(1,"x")]
#Iterating over each digit in octal
for digit in [int(n) for n in str(octal)]:
#Checking for each of permission values
for value, letter in value_letters:
if digit >= value:
result += letter
digit -= value
else:
result += "-"
return result
print(octal_to_string(755))
Output:
rwxr-xr-x
For a quick fix, just replace the pass with result += '-'; for every permission test that is False you can simply insert a dash:
for value, letter in value_letters:
if digit >= value:
result += letter
digit -= value
else:
result += '-'
I'd just use bit masking however, with the & bitwise and operator:
for value, letter in value_letters:
result += letter if digit & value else '-'
This works because 4, 2 and 1 are the decimal (and octal) values for numbers with each one of the 3 bits set to 1, the others to 0. digit & 4 is only going to produce 4 or 0, depending on the value of the 3rd bit from the right being set in digit or not. Since 0 is false, and 4 is a true value, this lets you test if the right bit is set and so decide between the permission letter and -. I used a conditional expression to return either in a single line.
Next, I'd not use a list comprehension to convert the input value into octal digits; just use map() here to lazily convert without creating an additional list object:
for digit in map(int, str(octal)):
Next, try to avoid using string concatenation in a loop; although Python has some optimisations in place to avoid the worst case performance in simple situations, you can easily miss out on that optimisation. Best to append characters to a list then use str.join() to create the final string in one step.
Put together into a complete function:
def octal_to_string(octal):
result = []
for digit in map(int, str(octal)):
for value, letter in ((4, "r"), (2, "w"), (1, "x")):
result.append(letter if digit & value else "-")
return "".join(result)
Demo:
>>> octal_to_string(755)
'rwxr-xr-x'
>>> octal_to_string(644)
'rw-r--r--'
Now, what the function accepts are decimal numbers, not octal numbers. From an API design you'd really want to either accept strings only (containing digits representing an octal value), or if you do accept an integer, then you should treat that value as decimal and use 0o octal notation:
>>> 0o755 # actual octal number
493
>>> format(0o755, "o") # string representing value in octal notation
'755'
If you do so, just change str(octal) into format(octal, 'o') to get the octal digits:
>>> octal = 0o755
>>> for digit in map(int, format(octal, "o")):
... print(digit)
...
...
7
5
5
def octal_to_string(octal):
result = ""
value_letters = [(4,"r"),(2,"w"),(1,"x")]
# Iterate over each of the digits in octal
for digits in [int(n) for n in str(octal)]:
# Check for each of the permissions values
for value, letter in value_letters:
if digits >= value:
result += letter
digits -= value
else:
result += "-"
return result
I am trying to square the every digit in a number provided by the user. I am getting the correct output but I get an additional index at the end I'm not really sure why. I've put comments in my code to explain what I'm trying to do at every step. How do I get rid of that index on the end?
def square_digits(num):
print(num)
string_num =(str(num)) #convert the num to a string
for word in string_num: #iterate through every digit
word = int(word) #convert each digit to an int so we can square it
square_num = word * word
str_sq_num = list(str(square_num)) #create a list of those nums
for count in str_sq_num: #iterate through list to make it one number
print(count, end = "")
print(str_sq_num)
return str_sq_num
So an example number is being given 3212. I should output 9414, instead my output is 9414['4']. Another example is a number 6791, the output should be 3649811, but my output is 3649811['1'].
The problem is the way for loops work in python. The variable str_square_num is left over from the last iteration of for word in string_num.
For example, assuming your number is 12, in the first iteration str_square_num will be [1], or 1 squared. But this value is overriden in the second iteration, when it is set to [4], or 2 squared. Thus the array will always contain only the square of the last digit.
If your goal is to get the array of all indicies, try this:
def square_digits(num):
print(num)
string_num =(str(num)) #convert the num to a string
str_sq_num = []
for word in string_num: #iterate through every digit
word = int(word) #convert each digit to an int so we can square it
square_num = word * word
str_sq_num.extend(str(square_num)) #create a list of those nums
for count in str_sq_num: #iterate through list to make it one number
print(count, end = "")
print(str_sq_num)
return str_sq_num
I'm not sure exactly what you're trying to achieve here, but looking at your examples I suppose this should work:
def square_digits(num):
print(num)
string_num = (str(num))
str_sq_num = []
for word in string_num:
word = int(word)
square_num = word * word
str_sq_num.append(square_num)
for count in str_sq_num:
print(count, end = "")
return str_sq_num
Couldn't test it, but this should do it:
def square_digits(string_num):
return "".join([str(int(num)**2) for num in string_num])
So my programming assignment wants me to take a user inputted list of numbers, ints and floating, and then order them in descending order and replace any of the floating with "0". I have got the reorder part done but the replace is getting me lost.
Reading Numbers
Write a program that shall ask the user to enter several integer numbers on
the same line, separated by vertical bars surrounded by zero or more spaces
(e.g., “|” or “ |” or “| ” or “ | ”). The program then shall display the entered
numbers in the descending sorted order (from the largest to the smallest),
all on the same line, separated by vertical bars and spaces (“ | ”). If
any entry on the command line is not an integer number, the program shall
replace it with a 0. Use only “for” loop(s) or list comprehensions. Use exception
handling.
# takes input and split them to get a list
numbers = input("Please enter numbers separated by vertical bars '|' :
").split("|")
# replace the floating numbers with "0"
for number in numbers:
print(type(number))
if number.isdigit() == False:
numbers.replace(number,'0')
# takes the list and reverse order sort and prints it with a "|" in between
numbers.sort(key = float , reverse = True)
[print(number,end = ' | ') for number in numbers]
One change I made was switching all of the for number in numbers to for i in range(len(numbers)). This allows you to access the actual variable by index, while for number in numbers just gets the value.
Here is my solution. I tried to add comments to explain why I did what I did, but if you have any questions, leave a comment:
# takes input and split them to get a list
numbers = input("Please enter numbers separated by vertical bars '|'\n").split(
"|")
# strip any extra spaces off the numbers
for i in range(len(numbers)):
numbers[i] = numbers[i].strip(" ")
# replace the floating numbers and strings with "0"
for i in range(len(numbers)):
try:
# check if the number is an int and changes it if it is
numbers[i] = int(numbers[i])
except:
# set the item to 0 if it can't be converted to a number
numbers[i] = 0
# takes the list and reverse order sort and prints it with a "|" in between
numbers.sort(reverse = True)
# changes the numbers back into strings
numbers = [str(numbers[i]) for i in range(len(numbers))]
# makes sure that there are more than one numbers before trying
# to join the list back together
if len(numbers) > 1:
print(" | ".join(numbers))
else:
print(numbers[0])
the instructions permit you to use exceptions. the following should get you most of the way there.
>>> numbers = ['1', '1.5', 'dog', '2', '2.0']
>>> for number in numbers:
>>> try:
>>> x = int(number)
>>> except:
>>> x = 0
>>> print(x)
1
0
0
2
0
Given a number number such that its digits are grouped into parts of length n (default value of n is 3) where each group represents some ascii value, I want to convert number into a string of those ascii characters. For example:
n number Output
==================================
3 70 F
3 65066066065 ABBA
4 65006600660065 ABBA
Note that there is no leading 0 in number, so the first ascii value will not necessarily be represented with n digits.
My current code looks like this:
def number_to_string(number, n=3):
number = str(number)
segment = []
while number:
segment.append(number[:n])
number = number[n:]
return str(''.join('{:0>{}}'.format(chr(segment), n) for segment in number))
Expected outputs:
number_to_string(70)
'F'
number_to_string(65066066065)
'ABBA'
number_to_string(65006600660065, n=4)
'ABBA'
My current code however returns an empty string. For example, instead of 'F' it returns ' '. Any reason why this is? Thank you!
P.S.:
I'm wanting to reverse the process of this question, i.e. turn an integer into a string based on the ascii values of each character (number) in the string. But reading that question is not a requirement to answer this one.
Try this:
import re
def number_to_string(num, n=3):
num_str = str(num)
if len(num_str) < n:
num_str = '0' * (n-len(num_str)) + num_str
elif len(num_str) % n != 0:
num_str = '0'*(n-len(num_str)%n) + num_str
print(num_str)
chars = re.findall('.'*n, num_str)
l = [chr(int(i)) for i in chars]
return ''.join(l)
First pad the given number (converted into string) with required number of zeros, so that it can be evenly split into equal number of characters each. Then using re split the string into segments of size n. Finally convert each chunk into character using chr, and then join them using join.
def numToStr(inp):
"""Take a number and make a sequence of bytes in a string"""
out=""
while inp!=0:
out=chr(inp & 255)+out
inp=inp>>8
print "num2string:", out
return out
does this help?
Is this what you want?
def num_to_string(num, leng):
string = ""
for i in range(0,len(str(num)),leng):
n = str(num)[i:i+2]
string += chr(int(n))
print string
Output:
>>> ================================ RESTART ================================
>>>
>>> num_to_string(650065006600,4)
AAB
>>> num_to_string(650650660,3)
AAB
>>> num_to_string(656566,2)
AAB
>>>
You can just append \x to number as this prints 'p':
print '\x70'
I am trying to take two long input integers (up to 10 digits) separated by space and display there sum.
I took the input into a string which are separated by space and then split them. After that I type caste them to int.
print "Enter two numbers"
a = raw_input()
a.split(" ")
sum = int(a[0]) + int(a[2])
print "\r", sum
Here I am not able to print the sum if the numbers are of even two digits.
You ignored the return value of str.split():
a.split(" ")
Assign that back to a:
a = a.split(" ")
Python strings are immutable, you cannot split the value of a in-place (let alone replace the type, splitting returns a list object rather than a new string).