Before this question is immediately marked as a duplicate let me say that I have already tried every solution which were the two questions most relevant to my situation. I would appreciate it if someone could at least look at my particular issue before closing this question if necessary.
I have a finite state machine object called e which is a MCFiniteSM object. At the core of e is a dictionary called state_dict which stores "process" ids ('1', '2', etc) and an associated dictionary which stores more information about each "process". I am running unittests to add processes, changes their states based on given parameters, etc. However, in between function calls in the unittest file the finite state machine seems to be cleared. I have looked at the two questions listed above in order to avoid this and persist changes but no matter what I try the changes to the finite state machine are not persisted. Here is the uniitest file.
from finite_state_machine import MCFiniteSM
from unittest import TestLoader, TestCase, main as unimain
from datetime import datetime
import time, calendar
class MyUnitTest(TestCase):
#classmethod
def setUpClass(cls):
cls.e = MCFiniteSM()
cls.timestamp = datetime.strftime(datetime.fromtimestamp(calendar.timegm(time.gmtime())), '%Y/%m/%d %H:%M:%S')
class TestFSM(MyUnitTest):
#classmethod
def setUpClass(cls):
super(TestFSM, cls).setUpClass()
#e = MCFiniteSM()
#timestamp = datetime.strftime(datetime.fromtimestamp(calendar.timegm(time.gmtime())), '%Y/%m/%d %H:%M:%S')
def test_add_convert_processes(self):
self.e.add_process('1', 'S', self.timestamp, 100, 'start message for process 1')
self.e.add_process('2', 'S', self.timestamp, 200, 'start message for process 2')
self.e.add_process('3', 'S', self.timestamp, 300, 'start message for process 3')
self.e.add_process('4', 'S', self.timestamp, 400, 'start message for process 4')
self.e.add_process('5', 'S', self.timestamp, 500, 'start message for process 5')
self.e.add_process('6', 'S', self.timestamp, 600, 'start message for process 6')
self.assertEqual(self.e.state_dict['1'], {'id':'1', 'message_type': 'S', 'timestamp':self.timestamp, 'state': 'i', 'threshold':100, 'message': 'start message for process 1'})
self.assertEqual(self.e.state_dict['2'], {'id':'2', 'message_type': 'S', 'timestamp':self.timestamp, 'state': 'i', 'threshold':200, 'message': 'start message for process 2'})
self.assertEqual(self.e.state_dict['3'], {'id':'3', 'message_type': 'S', 'timestamp':self.timestamp, 'state': 'i', 'threshold':300, 'message': 'start message for process 3'})
self.assertEqual(self.e.state_dict['4'], {'id':'4', 'message_type': 'S', 'timestamp':self.timestamp, 'state': 'i', 'threshold':400, 'message': 'start message for process 4'})
self.assertEqual(self.e.state_dict['5'], {'id':'5', 'message_type': 'S', 'timestamp':self.timestamp, 'state': 'i', 'threshold':500, 'message': 'start message for process 5'})
self.assertEqual(self.e.state_dict['6'], {'id':'6', 'message_type': 'S', 'timestamp':self.timestamp, 'state': 'i', 'threshold':600, 'message': 'start message for process 6'})
self.e.convert_state('1', 'S')
self.e.convert_state('2', 'S')
self.e.convert_state('3', 'S')
self.e.convert_state('4', 'S')
self.e.convert_state('5', 'S')
self.e.convert_state('6', 'S')
self.assertEqual(self.e.state_dict['2']['state'], 'a')
self.assertEqual(self.e.state_dict['3']['state'], 'a')
self.assertEqual(self.e.state_dict['4']['state'], 'a')
self.e.add_process('2', 'E', self.timestamp, None, 'end message for process 2')
self.e.add_process('3', 'E', self.timestamp, None, 'end message for process 3')
self.e.add_process('4', 'E', self.timestamp, None, 'end message for process 4')
self.assertEqual(self.e.state_dict['2']['state'], 'i')
self.assertEqual(self.e.state_dict['3']['state'], 'i')
self.assertEqual(self.e.state_dict['4']['state'], 'i')
def test_active_start_conversion(self):
print self.e
print 'trying...'
import sys
from StringIO import StringIO
orig = sys.stdout
try:
output = StringIO()
sys.stdout = output
self.e.convert_state('1', 'S')
out = output.getvalue().strip()
test = "Process ID:", '1', "\n" \
"Process Message Type:", 'S', "\n" \
"Process timestamp:", self.timestamp, "\n" \
"Process Threshold:", 100, "\n" \
"Process Message:", 'start message for process 1', "\n" \
"Log Message:", "PROCESS WITH ID 1 SENT MULTIPLE START MESSAGES", "\n"
self.assertEqual(out, test)
finally:
sys.stdout = orig
if __name__ == '__main__':
unimain()
'e' is the variable I want to keep modified between function calls. When I get down to TestFSM.test_active_start_conversion the size of e prints out 0, when it should be 6. The TestFSM.test_add_convert_processes method runs successfully.
The actual error is a key error. Here is the stack trace:
Error
Traceback (most recent call last):
File "/home/Desktop/fsm_unit_tests.py", line 68, in test_active_start_conversion
self.e.convert_state('1', 'S')
File "/home/Desktop/finite_state_machine.py", line 26, in convert_state
cb_id = self.state_dict[id]['id']
KeyError: '1'
The line where the error is thrown is the self.e.convert_state('1', 'S') where I am telling the fsm to change the state of the process with ID '1'. It believes that there is no process with ID 1 and upon printing the size of the fsm it believes the finite state machine is empty. This must be due to the fact that e is not continually maintained but I do not see why.
I have tried converting self.e to self.__class__.e (same with timestamp) as well as just keeping e and timestamp global and calling TestFSM.e and TestFSM.timestamp to persist changes. Both these solutions were listed in the other questions, both of them still produced a Key Error. I tried setting up setUpClass(), but that still produced a key error.
How can I persist e and timestamp?
Test methods are executed in alphabetical order. So test_active_start_conversion is executed before test_add_convert_processes.
However, really your tests should be independent - you should be doing the set up in the actual setUp method, not in a test method.
Related
trying to pass an array list of ec2 instance ids to my python script
#!/usr/bin/env python3
import boto3
import sys
import argparse
instance_id = list(sys.argv[1])
#aws_region = sys.argv[2]
tagname = sys.argv[2]
tagvalue = sys.argv[3]
EC2_RESOURCE = boto3.resource('ec2', region_name='us-west-1')
def tag_instance(instance_id,tagname,tagvalue):
TAGS = [
{
'Key': tagname,
'Value': tagvalue
}
]
instances = EC2_RESOURCE.instances.filter(
InstanceIds=[
instance_id,
],
)
for instance in instances:
instance.create_tags(Tags=TAGS)
print(f'Tags successfully added to the instance {instance.id}')
tag_instance(instance_id,tagname,tagvalue)
but keep getting this error
Invalid type for parameter InstanceIds[0],
value: ['i', '-', '0', '9', '2', 'b', 'b', 'a', 'b', 'a',
'f', '1', 'e', '8', '2', 'f', '5', 'a', '1', ','],
type: <class 'list'>,
valid types: <class 'str'>
any ideas?
Looking at the error, the comma at the end of the instance name strikes me. I assume, you make some incorrect assumptions on how the command line is parsed.
Try the following. Change the following lines in your script:
instance_ids = sys.argv[1].split(",")
and
instances = EC2_RESOURCE.instances.filter(InstanceIds=instance_ids)
Then call the script as:
scriptname "instance1,instance2,instance3" tagname tagvalue
Alternatively, you can move tagname and tagvalue to position 1 and 2 and use position 3.. for the instance names:
tagname = sys.argv[1]
tagvalue = sys.argv[2]
instance_ids = sys.argv[3:]
Then call it:
scriptname tagname tagvalue instance1 instance2 instance3
A different point: Your print statement is indented incorrectly, it will only be executed after the loop. Correct your code as follows:
for instance in instances:
instance.create_tags(Tags=TAGS)
print(f'Tags successfully added to the instance {instance.id}')
I have this function that sniffs packets in a constant loop using pcap library in Python.
def interface_listening(interface):
try:
packets = pcap.pcap(name=interface)
except OSError as exception:
print('[-] Issue: {0}'.format(exception))
sys.exit(-1)
while True:
print('[+] Listening on interface {0}'.format(packets.name))
sys.stdout.flush()
packets.loop(0, ethernet_parse) #constant loop
The prototype of packets.loop is that it takes a callback function, in this case : ethernet_parse.
I do some parsing of the packets order by order , which means: Ethernet,Ip,Tcp until I arrive at TLS information. The goal is to extract some Client Hello information and output the data as a .json format.
The parsing of Client Hello is done like this:
def parse_client_hello(handshake):
if isinstance(handshake.data, dpkt.ssl.TLSClientHello):
client = dpkt.ssl.TLSClientHello(str(handshake.data))
HANDSHAKE['Client_Hello']['Version'] = tls_dictionary('tls_version',client.version)
session_id, pointer = parse(client.data, 1)
HANDSHAKE['Client_Hello']['Session ID'] = hexlify(session_id)
ciphersuites, pointer1 = parse(client.data[pointer:], 2)
ciphersuites, pretty_cipher_suites = parse_extension(ciphersuites, 'cipher_suites')
HANDSHAKE['Client_Hello']['Cipher Suites'] = pretty_cipher_suites
HANDSHAKE['Client_Hello']['Random'] = client.random
pointer += pointer1
compression_methods, pointer1 = parse(client.data[pointer:], 1)
compression_methods, pretty_compressions = parse_extension(compression_methods,
'compression_methods')
HANDSHAKE['Client_Hello']['Compression Method'] = pretty_compressions
HANDSHAKE is a dictionary that I used in order to print the data as a .json format.
HANDSHAKE = {
"Client_Hello" : {
'Handshake Type': 'unknown',
'Length': 'unknown',
'Version': 'unknown',
'Random': 'unknown',
'Session ID': 'unknown',
'Session ID Length': 'unknown',
'Cipher Suites': 'unknown',
'Compression Method': 'unknown'
}
}
My goal is to fill out this dictionary with the captured data in parse_client_hello function for each packet, and to use the json_read function in order to have a file that contains all the captured data of "Client Hello" printed as a .json format.
def json_read(filename):
with open(filename, "w") as f:
json.dump(HANDSHAKE, f)
My question is: Where should I call the json_read function? If I call it just right after packets.loop of interface_listening function, it is never called.
I would be really grateful if you could answer this.
I have created a webhook for Dialogflow using Nodejs.
Now I need to call a Python file to summarize the text. I use python-shell for this action. As an argument, I add text that I want to shorten.
The problem is that the text about defenestration, for example, is sent correctly except for "v roce". Python will receive it as "v\xa0roce". The rest of the text is fine. Other text may have more than one this problem.
I tried to call Python with the same text as argument from the command line and this problem did not occur.
Code sample in Nodejs
var options = {
mode: 'text',
args: result
};
await PythonShell.run('summary.py', options, function (err, results) {
if(err){
console.log(err);
callback(result);
}
// results is an array consisting of messages collected during execution
else{
result = results.toString();
let output = {
fulfillmentText: result,
outputContexts: []
};
result = JSON.stringify(output);
callback(result);
}
});
If I call print (sys.argv [1]) at the beginning of the Python code, I get this
Původ slova je odvozován od pražské defenestrace v roce 1618, kdy
nespokojení protestanští stavové vyhodili z okna dva královské
místodržící a k tomuto činu sepsali obsáhlou apologii.
This looks good, but after doing this
article = filedata.split(". ")
sentences = []
for sentence in article:
sentences.append(sentence.replace("[^a-zA-Z]", " ").split(" "))
sentences.pop()
print(sentences)
return sentences
The following will return
"[['Defenestrace', 'označuje', 'násilné', 'vyhození', 'z', 'okna'],
['Původ', 'slova', 'je', 'odvozován', 'od', 'pražské', 'defenestrace',
'v\xa0roce', '1618,', 'kdy', 'nespokojení', 'protestanští',
'stavové', 'vyhodili', 'z', 'okna', 'dva', 'královské', 'místodržící',
'a', 'k', 'tomuto', 'činu', 'sepsali', 'obsáhlou', 'apologii'],
['Ovšem', 've', 'středověku', 'a', 'v', 'raném', 'novověku', 'se',
'defenestrace', 'konaly', 'poměrně', 'často', 'a', 'toto', 'konání',
'neslo', 'prvky', 'lynče,', 'ordálu', 'a', 'společně', 'spáchané',
'vraždy'], ['Ve', 'středověké', 'a', 'raně', 'novověké',
'společnosti,', 'která', 'je', 'výrazně', 'horizontálně', 'členěna,',
'má', 'defenestrace', 'charakter', 'symbolického', 'trestu']]"
I call this Python code using generate_summary(sys.argv[1], 2).
If I enter "TEXT ABOUT DEFENESTRATION" instead of sys.argv[1], this problem does not occur and is displayed "v roce".
Could someone help me?
Thank you in advance
Regular expressions are not supported in replace, you need to use re module instead like this:
re.sub("[^a-zA-Z]", " ", your_string)
And then split the result into words.
So i got this Bot for Instagram on GitHub .
I have edited the script so it run the longest time possible i guess ,until I have 3 ,"error 400" in a row then the script stop to prevent get banned.
I want to make a loop that, when I encountered an error, it closes and restart again.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import sys
import time
sys.path.append(os.path.join(sys.path[0], 'src'))
from check_status import check_status
from feed_scanner import feed_scanner
from follow_protocol import follow_protocol
from instabot import InstaBot
from unfollow_protocol import unfollow_protocol
bot = InstaBot(
login="USERNAME",
password="PASSWORD",
like_per_day=2500,
comments_per_day=1500,
tag_list=['photo', '', 'car', 'nature', 'city'],
tag_blacklist=['racist', 'example', 'example', 'example', ],
user_blacklist={},
max_like_for_one_tag=50,
follow_per_day=0,
follow_time=1 * 60,
unfollow_per_day=300,
unfollow_break_min=15,
unfollow_break_max=30,
log_mod=0,
proxy='',
# List of list of words, each of which will be used to generate comment
# For example: "This shot feels wow!"
comment_list=[["this", "the", "your"],
["photo", "picture", "pic", "shot", "snapshot"],
["is", "looks", "is really"],
["great", "super", "good", "very good", "good", "wow",
"WOW", "cool", "GREAT","magnificent", "magical",
"very cool", "stylish", "beautiful", "so beautiful",
"so stylish", "so professional", "lovely",
"so lovely", "glorious","so glorious",
"very glorious", "adorable", "excellent", "amazing"],
[".", "..", "...", "!", "!!", "!!!"]],
# Use unwanted_username_list to block usernames containing a string
## Will do partial matches; i.e. 'mozart' will block 'legend_mozart'
### 'free_followers' will be blocked because it contains 'free'
unwanted_username_list=[
'second', 'stuff', 'art', 'project', 'love', 'life', 'food', 'blog',
'free', 'keren', 'photo', 'graphy', 'indo', 'travel', 'art', 'shop',
'store', 'sex', 'toko', 'jual', 'online', 'murah', 'jam', 'kaos',
'case', 'baju', 'fashion', 'corp', 'tas', 'butik', 'grosir', 'karpet',
'sosis', 'salon', 'skin', 'care', 'cloth', 'tech', 'rental', 'kamera',
'beauty', 'express', 'kredit', 'collection', 'impor', 'preloved',
'follow', 'follower', 'gain', '.id', '_id', 'bags'
],
unfollow_whitelist=['example_user_1', 'example_user_2'])
while True:
#print("# MODE 0 = ORIGINAL MODE BY LEVPASHA")
#print("## MODE 1 = MODIFIED MODE BY KEMONG")
#print("### MODE 2 = ORIGINAL MODE + UNFOLLOW WHO DON'T FOLLOW BACK")
#print("#### MODE 3 = MODIFIED MODE : UNFOLLOW USERS WHO DON'T FOLLOW YOU BASED ON RECENT FEED")
#print("##### MODE 4 = MODIFIED MODE : FOLLOW USERS BASED ON RECENT FEED ONLY")
#print("###### MODE 5 = MODIFIED MODE : JUST UNFOLLOW EVERYBODY, EITHER YOUR FOLLOWER OR NOT")
################################
## WARNING ###
################################
# DON'T USE MODE 5 FOR A LONG PERIOD. YOU RISK YOUR ACCOUNT FROM GETTING BANNED
## USE MODE 5 IN BURST MODE, USE IT TO UNFOLLOW PEOPLE AS MANY AS YOU WANT IN SHORT TIME PERIOD
mode = 0
#print("You choose mode : %i" %(mode))
#print("CTRL + C to cancel this operation or wait 30 seconds to start")
#time.sleep(30)
if mode == 0:
bot.new_auto_mod()
elif mode == 1:
check_status(bot)
while bot.self_following - bot.self_follower > 200:
unfollow_protocol(bot)
time.sleep(10 * 60)
check_status(bot)
while bot.self_following - bot.self_follower < 400:
while len(bot.user_info_list) < 50:
feed_scanner(bot)
time.sleep(5 * 60)
follow_protocol(bot)
time.sleep(10 * 60)
check_status(bot)
elif mode == 2:
bot.bot_mode = 1
bot.new_auto_mod()
elif mode == 3:
unfollow_protocol(bot)
time.sleep(10 * 60)
elif mode == 4:
feed_scanner(bot)
time.sleep(60)
follow_protocol(bot)
time.sleep(10 * 60)
elif mode == 5:
bot.bot_mode = 2
unfollow_protocol(bot)
else:
print("Wrong mode!")
NOTE :
Editted some of the description to make it a little more readable and specific of what he/she is asking
*
Do error handling and put it in a while loop, and add some sleep to prevent suspension.
#here is an expamle of the code
while True:
try:
your codes here
expect:
code to show that error has occured
I realised I encounter so many errors because I did not had the requirement pyLint on my computer
If try to loop the entire process there is a chance of login error, because ad per instagram polices, you will not be able to login to instagram more than 5 time in a time period with same ip address. So you should only loop through the other process other than login
Code Here
from instabot import InstaBot
bot = InstaBot(login="USERNAME",password="PASSWORD")
while:
try:
//Your code here
expect:
//What to do if error occured
I'm trying to make a text adventure game, and my current approach involves lists/arrays that have valid commands:
#action verbs
act_verb = ['take', 'pick up', 'remove', 'shift', 'position', 'reposition', 'lift', 'kick', 'move']
#fight verbs
fight_verb = ['hit', 'kill', 'wack', 'dismember', 'destroy', 'obliterate']
#movement verbs
mov_verb = ['move', 'crawl', 'go', 'travel', 'walk', 'slither', 'go to', 'go to the', 'run']
#just-in-case adjectives
jic_adj = ['adjective']
#room nouns (ie directions, doors)
room_noun = ['north', 'n', 'south', 's', 'west', 'w', 'east', 'e', 'up', 'u', 'down', 'd']
#thing/object nouns
thing_noun = ['sword', 'troll', 'rug', 'door']
What I would like to do is be able to match two of those strings when a command is input, in a vein similar to this (but working, obviously):
command = raw_input('>')
if command == act_verb + thing_noun
print "output"
I've tried regular expressions, but can't seem to make them work, as I am not sure what the second argument required would be:
matchaverb = re.match(act_verb, )
matchtnoun = re.match(thing_noun, )
If anyone could provide some guidance or advice on how to continue, it would be greatly appreciated.
You would need to split on whitespace (command.split() without an argument does this) and then get the two commands. Then you can check:
if firstWord in act_verb and secondWord in thing_noun
It would be easier if your tokens would be without spaces, e.g. 'pick_up', 'go_to'. Then you can split the input this way:
tokens = command.split()
# get actions from command tokens:
actions = set(act_verbs) & set(tokens)
# process actions
if 'take' in actions:
....