i am new, program gives error "there are no type variables left in list" - typeerror

How the game works is that there is a 3-digit number, and you have to guess it. If you guess a digit in the right spot, you get a strike, and if you guess a digit but in the wrong spot you get a ball. I've coded it like this.
x = random.randint(1, 9)
y = random.randint(1, 9)
z = random.randint(1, 9)
userguessunlisted = input('What number do you want to guess?')
numbertoguess = list[x, y, z]
userguess = list(userguessunlisted)
b = 0
s = 0
while 0 == 0:
if userguess[0] == numbertoguess[0]:
s = s + 1
if userguess[0] == numbertoguess[1]:
b = b + 1
if userguess[0] == numbertoguess[2]:
b = b + 1
if userguess[1] == numbertoguess[0]:
b = b + 1
if userguess[1] == numbertoguess[1]:
s = s + 1
if userguess[1] == numbertoguess[2]:
b = b + 1
if userguess[2] == numbertoguess[0]:
b = b + 1
if userguess[2] == numbertoguess[1]:
b = b + 1
if userguess[2] == numbertoguess[2]:
s = s + 1
print(s + "S", b + "B")
if s != 3:
b = 0
s = 0
else:
print('you win!')
break

When you said list[x, y, z] on line 5, you used square brackets, which python interprets to be a type annotation. For example, if I wanted to specify that a variable is a list of ints, I could say
my_list_of_ints: list[int] = [1, 2, 3]
I think what you meant to do is create a new list from x, y, and z. One way to do this is
numbertoguess = list([x, y, z])
which is probably what you meant to write. This is valid because the list function takes an iterable as its one and only argument.
However, the list portion is redundant; square brackets on the right-hand side of an assignment statement already means "create a list with this content," so instead you should simply say
numbertoguess = [x, y, z]
A few other notes:
input will return a string, but you are comparing that string to integers further down, so none of the comparisons will ever be true. What you want to say is something like the following:
while True:
try:
userguessunlisted = int(input('What number do you want to guess?'))
except:
continue
break
What this code does is attempts to parse the string returned from input into an int. If it fails to do so, which would happen if the user inputted something other than a valid integer, an exception would be thrown, and the except block would be entered. continue means go to the top of the loop, so the input line runs repeatedly until a valid int is entered. When that happens, the except block is skipped, so break runs, which means "exit the loop."
userguessunlisted is only ever going to contain 1 number as written, so userguess will be a list of length 1, and all of the comparisons using userguess[1] and userguess[2] will throw an IndexError. Try to figure out how to wrap the code from (1) in another loop to gather multiple guesses from the user. Hint: use a for loop with range.
It might also be that you meant for the user to input a 3-digit number all at once. In that case, you can use a list comprehension to grab each character from the input and parse it into a separate int. This is probably a bit complicated for a beginner, so I'll help you out:
[int(char) for char in input('What number do you want to guess?')]
print(s + "S", b + "B") will throw TypeError: unsupported operand type(s) for +: 'int' and 'str'. There are lots of ways to combine non-string types with strings, but the most modern way is using f-strings. For example, to combine s with "S", you can say f"{s}S".
When adding some amount to a variable, instead of saying e.g. b = b + 1, you can use the += operator to more concisely say b += 1.
It's idiomatic in python to use snake_case for variables and Pascal case for classes. So instead of writing e.g. numbertoguess, you should use number_to_guess. This makes your code more readable and familiar to other python programmers.
Happy coding!

Related

Why is my conditional expression != ignored?

Here's my Fibonacci code using python 3.5
z = 0
x = 0
y = 1
while z != 317811:
x = x + y
z = x
print (z)
y = x + y
z = y
print (z)
I am wondering why this prints to infinity when setting the condition to
z != 317811
but works when it is below this number like
z != 196418
or a number greater than this like
z!= 514229
I tried a different approach (z <= 317811) but it prints up to 514229.
Thank you for your time.
KD
You're only testing alternate Fibonnaci numbers as the stopping condition: 317811 is getting missed.
One fix would be to test both x and y.
this is just logical problem
you are printing two
z != 317811
for this condition
"z"
is updated twice once in first z assignment i.e z = x
but "z" again get updated at second assignment z = y and then "z" is not sutisfying the condition(z != 317811) and not equal to 317811 but it is now 514229
Note: it will always work for number being printed at the second steps as this value of Z will be compared in while condition in loop
You are increasing z value twice a loop, but only checking once.
What actually is happening is that z is increasing with the fibonacci serie. Last values of z are:
196418
317811
514229
But you are only checking the stop condition once every two assignment. In this case you are checking that 196418 != 317811 and 514229 != 317811, thus never matching it.
One possible fix could be to test if z != 317811 after the first print. Even if in this case I would prefer testing "<" instead of "!="

Not sure what this pseudo-code is saying

I saw this pseudo-code on another stackoverflow question found here Split a string to a string of valid words using Dynamic Programming.
The problem is a dynamic programming question to see if an input string can be split into words from a dictionary.
The third line, means to set an array b of size [N+1] to all false values? I'm pretty sure about that. But what I am really not sure about is the fifth line. Is that a for-loop or what? I feel like pseudo-code saying 'for i in range' would only have 2 values. What is that line saying?
def try_to_split(doc):
N = len(doc)
b = [False] * (N + 1)
b[N] = True
for i in range(N - 1, -1, -1):
for word starting at position i:
if b[i + len(word)]:
b[i] = True
break
return b
It's confusing syntax, and I'm pretty sure there's a mistake. It should be:
for i in range(N - 1, 0, -1) //0, not -1
which I believe means
for i from (N - 1) downto 0 //-1 was the step, like i-- or i -= 1
This makes sense with the algorithm, as it simply starts at the end of the string, and solves each trailing substring until it gets to the beginning. If b[0] is true at the end, then the input string can be split into words from the dictionary. for word starting at position i just checks all words in the dictionary to see if they start at that position.
If one wants to be able to reconstruct a solution, they can change b to an int array, initialize to 0s, and change the if to this:
if b[i + len(word)] != 0
b[i] = i + len(word) //len(word) works too
break

Matlab: how do I run the optimization (fmincon) repeately?

I am trying to follow the tutorial of using the optimization tool box in MATLAB. Specifically, I have a function
f = exp(x(1))*(4*x(1)^2+2*x(2)^2+4*x(1)*x(2)+2*x(2)+1)+b
subject to the constraint:
(x(1))^2+x(2)-1=0,
-x(1)*x(2)-10<=0.
and I want to minimize this function for a range of b=[0,20]. (That is, I want to minimize this function for b=0, b=1,b=2 ... and so on).
Below is the steps taken from the MATLAB's tutorial webpage(http://www.mathworks.com/help/optim/ug/nonlinear-equality-and-inequality-constraints.html), how should I change the code so that, the optimization will run for 20 times, and save the optimal values for each b?
Step 1: Write a file objfun.m.
function f = objfun(x)
f = exp(x(1))*(4*x(1)^2+2*x(2)^2+4*x(1)*x(2)+2*x(2)+1)+b;
Step 2: Write a file confuneq.m for the nonlinear constraints.
function [c, ceq] = confuneq(x)
% Nonlinear inequality constraints
c = -x(1)*x(2) - 10;
% Nonlinear equality constraints
ceq = x(1)^2 + x(2) - 1;
Step 3: Invoke constrained optimization routine.
x0 = [-1,1]; % Make a starting guess at the solution
options = optimoptions(#fmincon,'Algorithm','sqp');
[x,fval] = fmincon(#objfun,x0,[],[],[],[],[],[],...
#confuneq,options);
After 21 function evaluations, the solution produced is
x, fval
x =
-0.7529 0.4332
fval =
1.5093
Update:
I tried your answer, but I am encountering problem with your step 2. Bascially, I just fill the my step 2 to your step 2 (below the comment "optimization just like before").
%initialize list of targets
b = 0:1:20;
%preallocate/initialize result vectors using zeros (increases speed)
opt_x = zeros(length(b));
opt_fval = zeros(length(b));
>> for idx = 1, length(b)
objfun = #(x)objfun_builder(x,b)
%optimization just like before
x0 = [-1,1]; % Make a starting guess at the solution
options = optimoptions(#fmincon,'Algorithm','sqp');
[x,fval] = fmincon(#objfun,x0,[],[],[],[],[],[],...
#confuneq,options);
%end the stuff I fill in
opt_x(idx) = x
opt_fval(idx) = fval
end
However, it gave me the output is:
Error: "objfun" was previously used as a variable, conflicting
with its use here as the name of a function or command.
See "How MATLAB Recognizes Command Syntax" in the MATLAB
documentation for details.
There are two things you need to change about your code:
Creation of the objective function.
Multiple optimizations using a loop.
1st Step
For more flexibility with regard to b, you need to set up another function that returns a handle to the desired objective function, e.g.
function h = objfun_builder(x, b)
h = #(x)(objfun(x));
function f = objfun(x)
f = exp(x(1))*(4*x(1)^2+2*x(2)^2+4*x(1)*x(2)+2*x(2)+1) + b;
end
end
A more elegant and shorter approach are anonymous functions, e.g.
objfun_builder = #(x,b)(exp(x(1))*(4*x(1)^2+2*x(2)^2+4*x(1)*x(2)+2*x(2)+1) + b);
After all, this works out to be the same as above. It might be less intuitive for a Matlab-beginner, though.
2nd Step
Instead of placing an .m-file objfun.m in your path, you will need to call
objfun = #(x)(objfun_builder(x,myB));
to create an objective function in your workspace. In order to loop over the interval b=[0,20], use the following loop
%initialize list of targets
b = 0:1:20;
%preallocate/initialize result vectors using zeros (increases speed)
opt_x = zeros(length(b))
opt_fval = zeros(length(b))
%start optimization of list of targets (`b`s)
for idx = 1, length(b)
objfun = #(x)objfun_builder(x,b)
%optimization just like before
opt_x(idx) = x
opt_fval(idx) = fval
end

How can I use a functor name like a variable in Prolog?

We have this assignment for our Prolog course. After two months of one hour per week of Prolog, it is still an enigma to me, my thinking seems unable to adapt from procedural languages - yet.
There is a knowledge base containing predicates/functors with the same name and arities 1, 2 and 3.
The call form should be
search(functor_name, argument, S).
The answers should find all occurrences with this functor name and argument, regardless of arity.
The answers should be of the form:
S = functor_name(argument);
S = functor_name(argument,_);
S = functor_name(_,argument);
S = functor_name(argument,_,_);
S = functor_name(_,argument,_);
S = functor_name(_,_,argument);
false.
I have found out that I could use call to test if the entry in the knowledge base exists.
But call does not seem to work with a variable for the functor name. I am totally baffled, no idea how to use a variable for a functor name.
UPDATE:
My question has been partly answered.
My new code gives me true and false for arities 1, 2 and 3 (see below).
search(Person,Predicate) :-
ID = Person, Key = Predicate, current_functor(Key,1),
call(Key,ID)
; ID = Person, Key = Predicate, current_functor(Key,2),
(call(Key,ID,_);call(Key,_,ID))
; ID = Person, Key = Predicate, current_functor(Key,3),
(call(Key,ID,_,_);call(Key,_,ID,_);call(Key,_,_,ID)).
UPDATE2:
Another partial answer has come in. That one gives me S as a list of terms, but the "other" arguments are placeholders:
search2(Predicate, Arg, S) :-
( Arity = 2 ; Arity = 3 ; Arity = 4 ),
functor(S, Predicate, Arity),
S =.. [_,Predicate|Args],
member(Arg, Args).
The result is quite nice. Still missing: the Predicate should not be inside the brackets and the other arguments should be taken literally from the knowledge base, not written as placeholders. The current result looks like this:
?- search2(parent,lars,S).
S = parent(parent, lars) ;
S = parent(parent, lars, _G1575) ;
S = parent(parent, _G1574, lars) ;
S = parent(parent, lars, _G1575, _G1576) ;
S = parent(parent, _G1574, lars, _G1576) ;
S = parent(parent, _G1574, _G1575, lars).
I am giving up with this question, because the question was posed in the wrong way from the beginning. I should have asked more specifically - which I could not, because I am still no good in Prolog.
#false helped me most. I am accepting his answer.
There are two approaches here, one "traditional" (1970s) that implements literally what you want:
search(F, Arg, S) :-
( N = 1 ; N = 2 ; N = 3 ), % more compactly: between(1,3, N)
functor(S, F, N),
S =.. [_|Args], % more compactly: between(1,N, I), arg(I,S,Arg)
member(Arg, Args).
The other reconsiders the explicit construction of the goal. Actually, if you have a functor F, and arguments A1, A2, A3 you can immediately write the goal call(F, A1, A2, A3) without any use of functor/3 or (=..)/2.
There are many advantages of using call(F, A1, A2, A3) in place of Goal =.. [F, A1, A2, A3], call(Goal): In many situations it is cleaner, faster, and much easier to typecheck. Further, when using a module system, the handling of potential module qualifications for F will work seamlessly. Whereas (=..)/2 will have to handle all ugly details explicitly, that is more code, more errors.
search(F,A,call(F,A)).
search(F,A,call(F,A,_)).
search(F,A,call(F,_,A)).
search(F,A,call(F,A,_,_)).
search(F,A,call(F,_,A,_)).
search(F,A,call(F,_,_,A)).
If you want to shorten this, then rather construct call/N dynamically:
search(F, Arg, S) :-
( N = 2 ; N = 3 ; N = 4 ),
functor(S, call, N),
S =.. [_,F|Args],
member(Arg, Args).
Note that call needs an extra argument for the functor F!
You can use the "univ" operator, =.., to construct a goal dynamically:
?- F=member, X=1, L=[1,2,3], Goal =.. [F, X, L], call(Goal).
F = member,
X = 1,
L = [1, 2, 3],
Goal = member(1, [1, 2, 3]) .

Translating Morse code with no spaces

I have some Morse code that has lost the spaces in between the letters, my challenge is to find out what the message says. So far I have been kinda lost because of the sheer amount of combinations there might be.
Here is all the info on the messages I have.
The output will be English
There will always be a translation that make sense
Here is and example message -..-...-...-...-..-.-.-.-.-..-.-.-.-.-.-.-.-.-.-..-...-.
The messages should be no longer then 70 characters
The morse code was taken from a longer stream so it is possible that the first or last groups may be cut off and hence have no valid translation
Does anyone have a clever solution?
This is not an easy problem, because as ruakh suggested there are many viable sentences to a given message. For example 'JACK AND JILL WENT UP THE HILL' has the same encoding as 'JACK AND JILL WALK CHISELED'. Since these are both grammatical sentences and the words in each are common, it's not obvious how to pick one or the other (or any other of the 40141055989476564163599 different sequences of English words that have the same encoding as this message) without delving into natural language processing.
Anyway, here's a dynamic programming solution to the problem of finding the shortest sentence (with the fewest characters if there's a tie). It can also count the total number of sentences that have the same encoding as the given message. It needs a dictionary of English words in a file.
The next enhancements should be a better measure of how likely a sentence is: perhaps word frequencies, false-positive rates in morse (eg, "I" is a common word, but it appears often as part of other sequences of morse code sequences). The tricky part will be formulating a good score function that can be expressed in a way that it can be computed using dynamic programming.
MORSE = dict(zip('ABCDEFGHIJKLMNOPQRSTUVWXYZ', [
'.-', '-...', '-.-.', '-..', '.', '..-.', '--.', '....',
'..', '.---', '-.-', '.-..', '--', '-.', '---', '.--.',
'--.-', '.-.', '...', '-', '..-', '...-', '.--', '-..-',
'-.--', '--..'
]))
# Read a file containing A-Z only English words, one per line.
WORDS = set(word.strip().upper() for word in open('dict.en').readlines())
# A set of all possible prefixes of English words.
PREFIXES = set(word[:j+1] for word in WORDS for j in xrange(len(word)))
def translate(msg, c_sep=' ', w_sep=' / '):
"""Turn a message (all-caps space-separated words) into morse code."""
return w_sep.join(c_sep.join(MORSE[c] for c in word)
for word in msg.split(' '))
def encode(msg):
"""Turn a message into timing-less morse code."""
return translate(msg, '', '')
def c_trans(morse):
"""Construct a map of char transitions.
The return value is a dict, mapping indexes into the morse code stream
to a dict of possible characters at that location to where they would go
in the stream. Transitions that lead to dead-ends are omitted.
"""
result = [{} for i in xrange(len(morse))]
for i_ in xrange(len(morse)):
i = len(morse) - i_ - 1
for c, m in MORSE.iteritems():
if i + len(m) < len(morse) and not result[i + len(m)]:
continue
if morse[i:i+len(m)] != m: continue
result[i][c] = i + len(m)
return result
def find_words(ctr, i, prefix=''):
"""Find all legal words starting from position i.
We generate all possible words starting from position i in the
morse code stream, assuming we already have the given prefix.
ctr is a char transition dict, as produced by c_trans.
"""
if prefix in WORDS:
yield prefix, i
if i == len(ctr): return
for c, j in ctr[i].iteritems():
if prefix + c in PREFIXES:
for w, j2 in find_words(ctr, j, prefix + c):
yield w, j2
def w_trans(ctr):
"""Like c_trans, but produce a word transition map."""
result = [{} for i in xrange(len(ctr))]
for i_ in xrange(len(ctr)):
i = len(ctr) - i_ - 1
for w, j in find_words(ctr, i):
if j < len(result) and not result[j]:
continue
result[i][w] = j
return result
def shortest_sentence(wt):
"""Given a word transition map, find the shortest possible sentence.
We find the sentence that uses the entire morse code stream, and has
the fewest number of words. If there are multiple sentences that
satisfy this, we return the one that uses the smallest number of
characters.
"""
result = [-1 for _ in xrange(len(wt))] + [0]
words = [None] * len(wt)
for i_ in xrange(len(wt)):
i = len(wt) - i_ - 1
for w, j in wt[i].iteritems():
if result[j] == -1: continue
if result[i] == -1 or result[j] + 1 + len(w) / 30.0 < result[i]:
result[i] = result[j] + 1 + len(w) / 30.0
words[i] = w
i = 0
result = []
while i < len(wt):
result.append(words[i])
i = wt[i][words[i]]
return result
def sentence_count(wt):
result = [0] * len(wt) + [1]
for i_ in xrange(len(wt)):
i = len(wt) - i_ - 1
for j in wt[i].itervalues():
result[i] += result[j]
return result[0]
msg = 'JACK AND JILL WENT UP THE HILL'
print sentence_count(w_trans(c_trans(encode(msg))))
print shortest_sentence(w_trans(c_trans(encode(msg))))
I don't know if this is "clever", but I would try a breadth-first search (as opposed to the depth-first search implicit in BRPocock's regex idea). Suppose your string looks like this:
.---.--.-.-.-.--.-...---...-...-..
J A C K A N D J I L L
You start out in state ('', 0) ('' being what you've decoded so far; 0 being your position in the Morse-code string). Starting from position zero, possible initial characters are . E, .- A, .-- W, .--- J, and .---- 1. So, push states ('E', 1), ('A', 2), ('W', 3), ('J', 4), and ('1', 5) onto your queue. After dequeuing state ('E', 1), you would enqueue states ('ET', 2), ('EM', 3), and ('EO', 4).
Now, your queue of possible states will grow quite quickly — both of { ., - } are letters, as are all of { .., .-, -., -- } and all of { ..., ..-, .-., .--, -.., -.-, --., --- }, so in each pass your number of states will increase by a factor of at least three — so you need to have some mechanism for user feedback. In particular, you need some way to ask your user "Is it plausible that this string starts with EOS3AIOSF?", and if the user says "no", you will need to discard state ("EOS3AIOSF", 26) from your queue. The ideal would be to present the user with a GUI that, every so often, shows all current states and lets him/her select which ones are worth proceeding with. ("The user" will also be you, of course. English has a shortage of pronouns: if "you" refers to the program, then what pronoun refers to the user-programmer?!)
Maintain 3 things: a list of words so far S, the current word so far W, and the current symbol C.
S should be only good words, eg. 'THE QUICK'
W should be a valid prefix of a word, eg. ['BRO']
C should be a valid prefix of some letter, eg. '.-'
Now, given a new symbol, let's say '-', we extend C with it (in this case we get '.--').
If C is a complete letter (in this case it is, the letter 'W'), we have a choice to add it to W, or to continue extending the letter further by adding more symbols.
If we extend W, we have a choice to add it to S (if it's a valid word), or to continue extending it further.
This is a search, but most paths terminate quickly (as soon as you have W not being a valid prefix of any word you can stop, and as soon as C isn't a prefix of any letter you can stop).
To get it more efficient, you could use dynamic programming to avoid redundant work and use tries to efficiently test prefixes.
What might the code look like? Omitting the functions 'is_word' which tests if a string is an English word, and 'is_word_prefix' which tests if a string is the start of any valid word, something like this:
morse = {
'.-': 'A',
'-...': 'B',
etc.
}
def is_morse_prefix(C):
return any(k.startswith(C) for k in morse)
def break_words(input, S, W, C):
while True:
if not input:
if W == C == '':
yield S
return
i, input = input[0], input[1:]
C += i
if not is_morse_prefix(C):
return
ch = morse.get(C, None)
if ch is None or not is_word_prefix(W + ch):
continue
for result in break_words(input, S, W + ch, ''):
yield result
if is_word(W + ch):
for result in break_words(input, S + ' ' + W + ch, '', ''):
yield result
for S in break_words('....--', [], '', ''):
print S