Trying to have two conditions for an if statement - python-3.6

Whenever I run this code, it always goes to the else statement. If the conditions for the signs being compatible are met, the output will always be not compatible. What am I doing wrong?
sign and sign2 are variables for zodiac signs. I am using zodiac sign elements to see if two signs are compatible with each other.
def zodiacCompatibility(sign, sign2):
fire = ["Aries, Leo, Sagittarius"]
earth = ["Capricorn, Taurus, Virgo"]
water = ["Pisces, Cancer, Scorpio"]
air = ["Gemini, Aquarius, Libra"]
if (sign in fire and sign2 in fire):
result = ("The two signs are compatible")
if (sign in earth and sign2 in earth):
result = ("The two signs are compatible")
if (sign in air and sign2 in air):
result = ("The two signs are compatible")
if (sign in water and sign2 in water):
result = ("The two signs are compatible")
if (sign in fire and sign2 in air):
result = ("The two signs are compatible")
if (sign in water and sign2 in earth):
result = ("The two signs are compatible")
if (sign in air and sign2 in fire):
result = ("The two signs are compatible")
if (sign in earth and sign2 in water):
result = ("The two signs are compatible")
else:
result = ("The two signs are not compatible")
finalResult = zodiacCompatibility(sign, sign2)
print (finalResult)

I think what you want to do is:
if (condition):
elif (condition):
elif (condition):
.
.
.
else:
What your code currently does is go through each if statement. If one or more of those conditions are satisfied it will write to result and then re-write over it again. The reason it goes to the else statement is because it is sign is not in earth and sign2 is not in water.
What I think you want is if none of the conditions are satisfied it goes to the else statement. This can be achieved to the structure I typed above.
[Here is more information]1 on how if statements and their counterparts work.

Related

How to re-prompt user input after incorrect type of data is given and also re prompt user input if they want to?

The program is about finding factors and if the user enters a special character or an alphabet it will show an error and I wanted to ask the user to try again "Invalid input please try again" after the error shows and also after the program shows the factors I wanted the user to have the chance to find another factor again "Try again? Yes/No"
I've tried the
while True:
if input("Try Again? (Yes/No)").strip().upper() == 'No':
break
but i don't know how to make it work.
Any other solutions will do
def print_factors(x):
print("The factors of",x,"are:")
for i in range(1, x + 1):
if x % i == 0:
print(i)
try:
num = int(input("Enter a number: "))
print_factors(num)
except ValueError:
print("Sorry, I didn't understand that.");
The program works and I just wanted to put some add ons
while True:
try:
num = int(input("Enter an integer (0 to exit): "))
if num == 0:
break
print(num)
except ValueError:
print("Sorry, you must enter an integer")

Program recurs in different line than supposed to

I have some rules called sessions that have a Title(String) and Topics (a list of String). I'm creating a query where I input some keywords and find which session has a best match. Each keyword can have a weight (keyword is followed by -2 for example if weight of keyword is 2, if weight is 1 there is nothing next to the keyword).
My problem is in the recursion. For inputs without weights everything is ok but with weights the program recurs differently.
session('Rules; Semantic Technology; and Cross-Industry Standards',
['XBRL - Extensible Business Reporting Language',
'MISMO - Mortgage Industry Standards Maintenance Org',
'FIXatdl - FIX Algorithmic Trading Definition Language',
'FpML - Financial products Markup Language',
'HL7 - Health Level 7',
'Acord - Association for Cooperative Operations Research and Development (Insurance Industry)',
'Rules for Governance; Risk; and Compliance (GRC); eg; rules for internal audit; SOX compliance; enterprise risk management (ERM); operational risk; etc',
'Rules and Corporate Actions']).
session('Rule Transformation and Extraction',
['Transformation and extraction with rule standards; such as SBVR; RIF and OCL',
'Extraction of rules from code',
'Transformation and extraction in the context of frameworks such as KDM (Knowledge Discovery meta-model)',
'Extraction of rules from natural language',
'Transformation or rules from one dialect into another']).
accessList([H|T], H, T).
is_empty_string(String) :-
String == ''.
not_empty_string(String) :-
String \== ''.
get_weight_of_token(MyToken, WeightOfToken) :-
split_string(MyToken,"-","",TempList), % tokenize MyToken into a list ( [string_of_token, weight_of_token] )
accessList(TempList,_,TempWeight), %
accessList(TempWeight,TempWeight2,_), % accessing the tail of the list (weight_of_token)
number_string(WeightOfToken,TempWeight2) % convert string to number
;
WeightOfToken is 1.
find_relevance([], SessionTitle, SessionTopics).
find_relevance([H | T], SessionTitle, SessionTopics) :-
get_weight_of_token(H, WeightOfToken),
format('Token = ~w with weight = ~d ~n', [H,WeightOfToken]),
format('Title = ~w~nTopics = ~w ~n', [SessionTitle,SessionTopics]),
find_relevance(T, SessionTitle, SessionTopics).
query(ListOfKeywords) :-
is_empty_string(ListOfKeywords), write('List of keywords is empty!')
;
not_empty_string(ListOfKeywords),
split_string(ListOfKeywords," ","",KeywordsTokens), %tokenize string with space as separator
session(Title,Topics), find_relevance(KeywordsTokens, Title, Topics), fail.
With an input without weights like 'firword secword', this is the result:
https://imgur.com/a/Q2fU2IM
As you can see the program recurs fine and calls find_revelance for the next session.
With an input with weights like 'firword-2 secword', this is the result:
https://imgur.com/xKFpFvh
As you can see the program doesn't recur to (9) for the next session but recurs to (10) for some reason.. and specifically to the part after ;..
Why is this happening? Thanks in advance.
*I changed the titles and topics to something smaller so the images can be more clear

How to make this function where I can give it an argument or not

So I made this very small function. it is a bonehead easy function but frankly borderline my capabilities.. Im learning. The function works as expected, but I would like to go further. I would like to make it so I can either give it an argument (a username) and just get the information for that single user, or default to reporting all users. is this possible w/o starting over from what I have so far?
I have just poked around and seen some examples but nothing that I can fit into my script. that I can understand at least.
import boto3
iam = boto3.client('iam')
def user_group():
for myusers in iam.list_users()['Users']:
Group = iam.list_groups_for_user(UserName=myusers['UserName'])
print("User: " + myusers['UserName'])
for groupName in Group['Groups']:
print("Group: " + groupName['GroupName'])
print("----------------------------")
user_group()
I would like to have the ability to run this script in two fashions.
1) add an argument(s) of 'username' so I can get the response for a particular user
2) default to getting response for all users if no argument is given.
This can be done by using an argument with a default value:
def user_group(user = None):
if user is None:
print("No user")
else:
print(user)
user_group()
user_group('some user')
prints
No user
some user
In your case you may want to write
def user_group(user = None):
users_to_list = iam.list_users()['Users'] if user is None else [user]
for myusers in user_to_list:
...

rkafka.read() doesn't return a message (Returns double quotes only)

Trying to return a message through rkafka library in R.
Followed the same rkafka documentation # https://cran.r-project.org/web/packages/rkafka/vignettes/rkafka.pdf
Output returns "" without the actual message in it. Kafka tool confirms that the message is sent by the producer.
CODE:
prod1=rkafka.createProducer("127.0.0.1:9092")
rkafka.send(prod1,"test","127.0.0.1:9092","Testing once")
rkafka.closeProducer(prod1)
consumer1=rkafka.createConsumer("127.0.0.1:2181","test")
print(rkafka.read(consumer1))
Output:
[1] ""
Desired Output would return "Testing once".
In order to read the messages of a topic that have already been written to the topic (before the consumer has been started) you need to set offset value to the smallest possible (equivalent to --from-beginning). According to rkafka docs autoOffseetReset argument defaults to largest
autoOffsetReset
smallest : automatically reset the offset to the
smallest offset largest : automatically reset the offset to the
largest offset anything else: throw exception to the consumer
Required:Optional Type:String default:largest
In order to be able to consume messages you need to set autoOffsetReset to "smallest".
consumer1=rkafka.createConsumer("127.0.0.1:2181","test", autoOffsetReset="smallest")
Update: This Code Works:
library(rkafka)
prod1=rkafka.createProducer("127.0.0.1:9092")
rkafka.send(prod1,"test","127.0.0.1:9092","Testing once")
rkafka.send(prod1,"test","127.0.0.1:9092","Testing twice")
rkafka.closeProducer(prod1)
consumer1=rkafka.createConsumer("127.0.0.1:2181","test",groupId = "test-consumer-
group",zookeeperConnectionTimeoutMs = "100000",autoCommitEnable = "NULL",
autoCommitInterval = "NULL",autoOffsetReset = "NULL")
print(rkafka.read(consumer1))
print(rkafka.readPoll(consumer1))
rkafka.closeConsumer(consumer1)
The key is to restart Kafka after deleting the logs it generates.

Provide a list of numbers to Alexa

I want to create a lottery skill that takes 6 numbers from the user.
I'm currently learning by going through the samples and developer guides, and I can go through the guides and get a working skill that will take one input and then end the session. But I believe I need to create a dialog somehow, which is where I get stuck.
Design-wise, I'd like the dialog to go like this:
Alexa: Please provide the first number
User: 1
Alexa: and now the second...
User: 2
etc etc
But I think it would be OK if it went like this:
Alexa: Please call out 6 numbers
User: 1, 2, 3, 4, 5, 6.
Is this even possible? Will I have to create a custom slot type called "Numbers" and then put in the numbers, eg 1-50 or whatever the limit is?
At best, I can currently get it to ask for one number, so its really the dialog interaction that I'm stuck on. Has anyone ever even done anything like this?
Thanks.
Yes to both questions. You could string together a response with 6 different custom slots. "User: My numbers are {num1}, {num2}, {num3}, {num4}, {num5}, {num6} " and make them all required using the skills beta developer. However, it will be a rather bad user experience if the user does not phrase their answer appropriately and Alexa has to ask follow up questions to obtain each number. The last problem you'll run into is that while a custom slot could be defined to contain the numbers 1-50 alexa will generally recognize similar values to those provided in a custom slot, such as numbers from 50-99. It would then be up to you to check that the values you receive are between 1 and 50. If not you'd want to ask the user to provide a different number in the appropriate range.
Conclusion: You'll want to have individual interactions where a user provides a single number at a time.
Alexa:"you will be prompted for 6 numbers between 1 and 50 please state them one at a time. Choose your first number."
User:"50"
Alexa:"Your First number is 50, Next number."...
You can implement this using a single intent. let's name that intent GetNumberIntent. GetNumberIntent will have sample uterances along the line of
{number}
pick {number}
choose {number}
where {number} is a custom slot type or simply AMAZON.NUMBER. It will then be up to you to check that the number is between 1 and 50.
I program in Node.js using the SDK. Your implementation may vary depending upon your language choice.
What I would do is define 6 different state handlers. Each handler should have the GetNumberIntent. When a GetNumberIntent is returned if the slot value is apropriate store the value to the session data and or dynamodb and move forward to the next state. If the slot value is invalid stay for example at state "NumberInputFiveStateHandlers" until a good value is received then change state to the next "NumberInputSixStateHandlers"
var NumberInputFiveStateHandlers = Alexa.CreateStateHandler(states.NUMFIVEMODE, {
'NewSession': function () {
this.emit('NewSession'); // Uses the handler in newSessionHandlers
},
//Primary Intents
'GetNumberIntent': function () {
let message = ` `;
let reprompt = ` `;
let slotValue = this.event.request.intent.slots.number.value;
if(parseInt(slotValue) >= 1 && parseInt(slotValue) <= 50){
this.handler.state = states.NUMSIXMODE;
this.attributes['NUMBERFIVE'] = this.event.request.intent.slots.number.value;
message = ` Your fifth number is `+slotValue+`. please select your sixth value. `;
reprompt = ` please select your sixth value. `;
}else{
message = ` The number `+slotValue)+` is not in the desired range between 1 and 50. please select a valid fifth number. `;
reprompt = ` please select your fifth value. `;
}
this.emit(':ask',message,reprompt);
},
//Help Intents
"InformationIntent": function() {
console.log("INFORMATION");
var message = ` You've been asked to choose a lottery number between 1 and 50. Please say your selection.`;
this.emit(':ask', message, message);
},
"AMAZON.StopIntent": function() {
console.log("STOPINTENT");
this.emit(':tell', "Goodbye!");
},
"AMAZON.CancelIntent": function() {
console.log("CANCELINTENT");
this.emit(':tell', "Goodbye!");
},
'AMAZON.HelpIntent': function() {
var message = `You're playing lottery. you'll be picking six numbers to play the game. For help with your current situation say Information. otherwise you may exit the game by saying quit.`;
this.emit(':ask', message, message);
},
//Unhandled
'Unhandled': function() {
console.log("UNHANDLED");
var reprompt = ' That was not an appropriate response. Please say a number between 1 and 50.';
this.emit(':ask', reprompt, reprompt);
}
});
This is an example of the fifth request. You'll have 6 identical states like this one that string back to back. Eventually you'll end up with 6 session values.
this.attributes['NUMBERONE']
this.attributes['NUMBERTWO']
this.attributes['NUMBERTHREE']
this.attributes['NUMBERFOUR']
this.attributes['NUMBERFIVE']
this.attributes['NUMBERSIX']
You can then use these values for your game.
If you have not used the alexa-sdk before you must remember to register your state handlers and add your modes to the states variable.
alexa.registerHandlers(newSessionHandlers, NumberInputOneStateHandlers, ... NumberInputSixStateHandlers);
var states = {
NUMONEMODE: '_NUMONEMODE',
...
...
NUMSIXMODE: '_NUMSIXMODE',
}
This answer is not intended to cover the basics of coding using Alexas-SDK. There are other resourced for more specific questions on that topic.
Alternatively, because your intent is identical [GetNumberIntent], you may be able to get by with a single StateHandler that pushes new valid numbers onto an array until the array is the desired length. That would simply require more logic inside the Intent Handler and a conditional to break out of the state once the array is of length 6.
Try the code above first because it's easier to see the different states.

Resources