I'm currently trying to make a cipher program, here is my code;
import string
import random
matrix = []
codedmessage = []
letter = "ABCDEF"
message = input("Enter message to be encoded:\n").upper().replace(' ', '')
print ('---MESSAGE---\n', message)
newlist = list(string.ascii_uppercase + string.digits)
random.shuffle(newlist)
print ('---MATRIX---')
for x in range(0,len(newlist),6):
matrix.append(list(newlist[x:x+6]))
for letter in message:
for y, vector in matrix:
for s, member in vector:
if letter == member:
codedmessage.append(letter[x], letter[y])
for i in range(len(matrix)):
print(matrix[i])
However, when I compile this I get the error;
for y, vector in matrix: ValueError: too many values to unpack
(expected 2)
Can anyone shed some light on this as to why it is happening and give a solution?
Thanks
matrix.append(list(newlist[x:x+6]))
You append 6 element lists to matrix, but you try to unpack them into two variables later:
for y, vector in matrix:
The numbers have to match.
Currently you matrix looks like [ [4,3,2,6,3,2], [2,1,6,8,9,2], ... ]. How is python supposed to unpack one of the elements, for example [4,3,2,6,3,2] into y and vector? What should go where? (For possible solutions see the other answers, they were faster. I don't understand what behaviour is expected anyway.)
Also you cannot index a character:
codedmessage.append(letter[x], letter[y])
previously you assigned a single character to letter, here:
for letter in message:
because message is a string. You probably confuse names as you already have assigned a string to letter initially: letter = "ABCDEF" Probably you want to use two different names.
append does only take one argument, too. Again I don't know what you expect, but I guess it should be either codedmessage.append([letter[x], letter[y]]) or codedmessage += [letter[x], letter[y]].
I also highly doubt that you want to use x in codedmessage.append(letter[x], letter[y]) because you only used x in another independent loop as iteration variable.
Each element of matrix is a list of six items, so if you only provide two variable names on the left-hand side, Python doesn't know what to do with the other four.
However, you can (in Python 3) unpack back into a list like this:
>>> a, *b = [1,2,3,4,5,6]
>>> a
1
>>> b
[2, 3, 4, 5, 6]
Related
I am quite new to Python so I hope someone can point me in the right direction with my question.
I want to assign a specific numeric value (integer) to a character/letter in a word (i.e. given input).
For example:
My input is ‘vase’
v= 5
a= 2
s= 7
e= 1
So now I want to calculate the “word value” by for example addition, multiplication or division or something (e.g. from ‘vase’ to the total word value, which is an integer).
When I google , I keep finding dictionary examples, but they all seem to work from the idea that a=1, b=2, c=3 etc.
How would I be able to assign self chosen values to individual characters and then calculate with these numbers?
Edit: I should have been more clear. I want to calculate values based on the complete word. So I want to set up values for individual letters which can be used to transform any string input (in this case ‘vase’) into a final value per word.
I am not sure I understand your question and what you are trying to do. If I run the maths based on the number proviuded I see
>>> 5+2+7+1%2
15
>>>
If I assign the values to the characters v a s e as you show and use the characters I get the same answer
>>>
>>> v=5
>>> a=2
>>> s=7
>>> e=1
>>> word_val = v+a+s+e%2
>>> print(word_val)
15
>>>
Like the first comment said, make your own dictionary. This is what it will look like, try to run this code:
import random
i = input().strip()
d = {}
for c in i:
d[c] = random.randint(0,26)
print(d)
# Functions on the word, suppose add
sum = 0
for c in i:
sum = sum + d[c]
print(sum)
I am trying to recreate a for loop (A) into a list comprehension. I think the problem here is that there are too many functions that need to be done to ni, namely squaring it and then making sure it is an integer before appending onto nn .
The list comprehension (B) is an attempt at getting the list comprehension to take a string (m) and square each individual number as an integer. The problem is that it needs to iterate over each number as a string THEN square itself as individual integers.
A
n = str(2002)
nn = []
for x in range(len(n)):
ni = n[x]
ns = int(ni)**2
nn.append(ns)
print(nn)
[4, 0, 0, 4]
B
m = str(9119)
mm = [(int(m[x]))**2 for x in m]
TypeError: string indices must be integers
This makes me feel like A cannot be done as a list comprehension? Love to see what your thoughts for alternatives and/or straight up solutions are.
You are passing a string as the index!
Additionally, you were trying to index the string m with the number at each index instead of its index (e.g, you tried to index m[0] with m[9] instead)
Try using the following instead:
m = str(9119)
mm = [int(x)**2 for x in m] #Thanks #Gelineau
Hope this helps!
x represents each digit in m. So you just have to square it
mm = [int(x)**2 for x in m]
Hi I have just started an online course for python, just for me, and one of the exercises is asking me to add the first and list integer from a list you input, I think I have it, but not too sure as it keeps giving me an error,
ValueError: invalid literal for int() with base 10
my code is
userList = list(map(int, input().split(',')))
intTotal = userList[1] + userList[len userList]
print (intTotal)
now, how I understand it the, [1] would be the first userList value, as it is the first position in the list, and the [len userList] should give me last position as it is giving the length of list as position number.
then it should print the variable intTotal
If you could show me where i am going wrong if it all that would be ace!
Your error is most likely that your input is something like 1, 2, 3, 4, 5,
When you use split(',') on this, you will have an extra empty entry at the end of your list that you must account for. You can check for this in a list comprehension.
To access the last element of the list, you may use arr[len(arr)-1], or in Python which supports negative indexing, arr[-1].
Here is a working version of your code with the above changes made:
userList = [int(x.strip()) for x in input().split(',') if x]
intTotal = userList[0] + userList[-1]
print (intTotal)
Sample run:
>>>1, 2, 3, 4, 5,
6
You could make this even more robust to filter out bad input by using isdigit(), which would allow for the user to enter letters, but it would only add the first and last numbers entered:
userList = [int(x) for x in input().split(',') if x.isdigit()]
Sample run:
>>> 1,2,a,3,4,6,b,4
5
I'm learning Python. I have combined numbers and letters in one list. Next I wanted to choose only numbers and append them to another list. When the program encounters letters it gives me this error:
if not str(a[x]).isalpha(): TypeError: list indices must be integers,
not str
a = []
b = 'This is a dog'
d = [888, 999]
c = []
for i in range(10):
a.append(i)
a.extend(b)
for elem in d:
a.append(elem)
print(a)
print('---------------------------------')
for x in a:
if not str(a[x]).isalpha():
c.append(a[x])
print(c)
else:
pass
print(c)
I will appreciate if you can teach me in this case.
print('---------------------------------')
for x in a: # Here you'll get each value of a in x.
if not str(x).isalpha(): # So here you don't have to use a[x] but simply x.
c.append(x)
print(c)
else:
pass
What you are doing fails because at some point in x you have "This is a dog".
Asking for a[x] then means asking python to look for "this is a dog" as an index in a.
This fails and python tells you that lists only have integer indices, not strings.
Just as commented by some, the concept of list is like an array. It is ordered and thus is accessed by index, which is integer.
Just imagine if you have a row of rooms in a hotel or houses in the same street. It just makes sense if the houses or rooms are numbered to show that the objects are ordered. This goes the same for memory location for list. Thus, it is to be accessed by int.
However, it is quite different case when you deal with, say, dictionary. The concept is not that it must be ordered in a row, but as long as you have a key, you should be able to get the correct value for the key. This is, probably, more like how our brain works when we translate one language to another. As long as we have the word from one language (key) we could get the right translated word (value) in the other language (such as "centre" is English is translated to "Zhong" in Chinese). Thus the term dictionary is not too far off the reality (albeit in our dictionary book the words are usually ordered by alphabets, but we don't use it by number - but rather by searching the word we want to translate).
Now to answer your programming question, when you do for x in a you already get element of a one by one. You only need to check if not str(x).isalpha instead of accessing it by a[x]:
print(a)
print('---------------------------------')
for x in a:
if not str(x).isalpha(): #use x directly, x represents an element in a already
c.append(x)
print(c)
else:
pass
You see, python expression like "for x in a" where a is a list already gives you elements of that list, so no need for a[x].
This should work:
for x in a:
if not str(x).isalpha():
...
Thank you all for so much help. The code below is what I wanted to do.
a = []
b = 'This is a dog'
d = [888, 999]
c = []
for i in range(10):
a.append(i)
a.extend(b)
for elem in d:
a.append(elem)
print(a)
print('---------------------------------')
for x in a:
if str(x).isnumeric():
c.append(x)
print(c)
else:
pass
print(c)
I want to:
Take two inputs as integers separated by a space (but in string form).
Club them using A + B.
Convert this A + B to integer using int().
Store this integer value in list C.
My code:
C = list()
for a in range(0, 4):
A, B = input().split()
C[a] = int(A + B)
but it shows:
IndexError: list assignment index out of range
I am unable understand this problem. How is a is going out of the range (it must be starting from 0 ending at 3)?
Why it is showing this error?
Why your error is occurring:
You can only reference an index of a list if it already exists. On the last line of every iteration you are referring to an index that is yet to be created, so for example on the first iteration you are trying to change the index 0, which does not exist as the list is empty at that time. The same occurs for every iteration.
The correct way to add an item to a list is this:
C.append(int(A + B))
Or you could solve a hella lot of lines with an ultra-pythonic list comprehension. This is built on the fact you added to the list in a loop, but this simplifies it as you do not need to assign things explicitly:
C = [sum(int(item) for item in input("Enter two space-separated numbers: ").split()) for i in range(4)]
The above would go in place of all of the code that you posted in your question.
The correct way would be to append the element to your list like this:
C.append(int(A+B))
And don't worry about the indices
Here's a far more pythonic way of writing your code:
c = []
for _ in range(4): # defaults to starting at 0
c.append(sum(int(i) for i in input("Enter two space-separated numbers").split()))
Or a nice little one-liner:
c = [sum(int(i) for i in input("Enter two space-separated numbers").split()) for _ in range(4)]