Trouble answering a python syntax challenge - python

I received this challenge where if I run the code right, a flag should appear. A little disclaimer, my Python skills are rough to non-existent and I'll be glad to understand what is causing the syntax errors in the code, specifically when trying to run the line 15 "31/21" seems to cause the problem, but here's the code:
str = '''
_____ _ _____ _
/ __ \ | | |_ _| | |
| / \/_ _| |__ ___ _ __ | | ___ _ __ __ _ ___| |
| | | | | | '_ \ / _ \ '__| | |/ __| '__/ _` |/ _ \ |
| \__/\ |_| | |_) | __/ | _| |\__ \ | | (_| | __/ |
\____/\__, |_.__/ \___|_| \___/___/_| \__,_|\___|_|
__/ |
|___/
'''
print(str)
print("Congratulations on Completing Your Challenge!\n")
print("Please send your CV, the code "31/21" and your registered email to the challenge via our Email address: cyberm#cyber.gov.il\n")
input("Stay safe ;)")
Thanks in advance.

When you want a " character in a string you can use the single quote ' to delimit the whole string:
print('Please send your CV, the code "31/21" and your registered email to the challenge via our Email address: cyberm#cyber.gov.il\n')

Related

pywinauto - TimeComX Basic print_control_identifiers() doesn't show all the options

I want to have automate process for this program: TimeComX Basic.
The script i wrote:
from pywinauto.application import Application as PyWinAutoApplication
from pywinauto.timings import wait_until
from pywinauto.keyboard import send_keys
import pywinauto
import os
import sys
from pywinauto import mouse
import traceback
#Hidernate pc
app2 = PyWinAutoApplication(backend="uia").connect(found_index=0,title="TimeComX Basic")
handle = pywinauto.findwindows.find_windows(title="TimeComX Basic")[0]
window = app2.window(handle=handle)
window.maximize()
window.set_focus()
app2.TimeComxBasic.print_control_identifiers()
#mouse.click(button='left', coords=(150, 960))
Note that to run this script you have to manually install and open TimeComX Basic.
The output:
Control Identifiers:
Dialog - 'TimeComX Basic' (L-11, T-11, R1931, B1019)
['TimeComX BasicDialog', 'Dialog', 'TimeComX Basic']
child_window(title="TimeComX Basic", control_type="Window")
|
| TitleBar - '' (L24, T-8, R1920, B34)
| ['TitleBar']
| |
| | Menu - 'System' (L0, T0, R22, B22)
| | ['Menu', 'System', 'SystemMenu', 'System0', 'System1']
| | child_window(title="System", auto_id="MenuBar", control_type="MenuBar")
| | |
| | | MenuItem - 'System' (L0, T0, R22, B22)
| | | ['MenuItem', 'System2', 'SystemMenuItem']
| | | child_window(title="System", control_type="MenuItem")
| |
| | Button - 'Minimize' (L1707, T0, R1778, B33)
| | ['MinimizeButton', 'Button', 'Minimize', 'Button0', 'Button1']
| | child_window(title="Minimize", control_type="Button")
| |
| | Button - 'Restore' (L1778, T0, R1848, B33)
| | ['Restore', 'Button2', 'RestoreButton']
| | child_window(title="Restore", control_type="Button")
| |
| | Button - 'Close' (L1848, T0, R1920, B33)
| | ['Close', 'Button3', 'CloseButton']
| | child_window(title="Close", control_type="Button")
As you can see it has options only for close, minimize and maximize buttons and for main menu. There is no option to "Start" button for example.
What can I do in this situation?

Using Fabric to nest SSH connections in Python

I am trying to run a very basic script that opens a SSH session to a software defined router, then issue a command to connect to one of its branch routers. Exactly what would be happening if you just opened PuTTY and connected to it, then connected again. After it connects to the second router, I would like to issue a reboot command and close the connection.
I have been able to get Fabric to connect to the first router, enter the command and password, but am unable to get it to output to the second session. It's my understanding that this is just emulating the terminal in a way and this function should work. Says something along these lines in the docs but provides no examples.
The code
initpass = Responder(pattern = r't128#127.127.0.1\'s password:', response = 'password\n')
sudopass = Responder(pattern=r'[sudo] password for t128:', response='password\n')
conductor = Connection(host='admin#first.router.host', connect_kwargs={'password': 'password'})
conductor.run('connect router ASMPLBRT01 node ASMPLBRT01A username t128', pty=True, watchers=[initpass])
conductor.run('sudo shutdown', pty=False)
And this is the expected SSH output from a putty session.
Using username "admin".
End of banner message from server
admin#first.router's password:
Last login: Fri Feb 25 11:15:03 2022 from 192.168.13.243
Welcome to ConnX AIStarting the PCLI...
admin#firstrouter.firstrouterA# connect router second.router node second.routerA username t128
Connecting...
t128#127.127.0.1's password:
FIPS mode initialized. SSH client running in FIPS 140-2 mode
Last login: Fri Feb 25 11:41:08 2022 from second.router.host
+---------------------------------------------------------------------+
| Welcome to: |
| _ ____ ___ _ _ _ |
| / |___ \( _ )| |_ ___ ___| |__ _ __ ___ | | ___ __ _ _ _ |
| | | __) / _ \| __/ _ \/ __| '_ \| '_ \ / _ \| |/ _ \ / _` | | | | |
| | |/ __/ (_) | || __/ (__| | | | | | | (_) | | (_) | (_| | |_| | |
| |_|_____\___/ \__\___|\___|_| |_|_| |_|\___/|_|\___/ \__, |\__, | |
| |___/ |___/ |
| Secure Vector Routing ... |
| |
+---------------------------------------------------------------------+
[t128#second.router.host ~]$ sudo shutdown
We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:
#1) Respect the privacy of others.
#2) Think before you type.
#3) With great power comes great responsibility.
[sudo] password for t128:
Shutdown scheduled for Fri 2022-02-25 12:56:13 EST, use 'shutdown -c' to cancel.
[t128#asmplbrt01 ~]$
Broadcast message from root#asmplbrt01 (Fri 2022-02-25 12:55:13 EST):
The system is going down for power-off at Fri 2022-02-25 12:56:13 EST!
[t128#asmplbrt01 ~]$

Is there a way I can print the output of an input I converted on a singular line?

I was making this emoji encoder and basically I need to make it so that it prints the output of the
inputted text on one line instead of each character on separate lines. Right Now it just inputs the encoded text(the emojis) on separate lines, is there any way I can make it output on just one line. Any suggestions?
Edit: I solved the problem thanks everyone :)
import emoji
# Ascii Art
print('\n'
' ________ __ ________ __ \n'
'/ | / | / | / | \n'
'$$$$$$$$/ _____ ____ ______ __ $$/ $$$$$$$$/ _______ _______ ______ ____$$ | ______ ______ \n'
'$$ |__ / \/ \ / \ / |/ | $$ |__ / \ / | / \ / $$ | / \ / \ \n'
'$$ | $$$$$$ $$$$ |/$$$$$$ | $$/ $$ | $$ | $$$$$$$ |/$$$$$$$/ /$$$$$$ |/$$$$$$$ |/$$$$$$ |/$$$$$$ |\n'
'$$$$$/ $$ | $$ | $$ |$$ | $$ | / |$$ | $$$$$/ $$ | $$ |$$ | $$ | $$ |$$ | $$ |$$ $$ |$$ | $$/ \n'
'$$ |_____ $$ | $$ | $$ |$$ \__$$ | $$ |$$ | $$ |_____ $$ | $$ |$$ \_____ $$ \__$$ |$$ \__$$ |$$$$$$$$/ $$ | \n'
'$$ |$$ | $$ | $$ |$$ $$/ $$ |$$ | $$ |$$ | $$ |$$ |$$ $$/ $$ $$ |$$ |$$ | \n'
'$$$$$$$$/ $$/ $$/ $$/ $$$$$$/__ $$ |$$/ $$$$$$$$/ $$/ $$/ $$$$$$$/ $$$$$$/ $$$$$$$/ $$$$$$$/ $$/ \n'
' / \__$$ | \n'
' $$ $$/ \n'
' $$$$$$/ \n'
' \n'
'\n')
# Intro Loading Screen
print("Enter text to be encoded Here:")
text = input()
# Encoder for lower case
if "a" in text:
print(emoji.emojize(':grinning_face:'))
if "b" in text:
print(emoji.emojize(':grinning_face_with_smiling_eyes:'))
if "c" in text:
print(emoji.emojize(':beaming_face_with_smiling_eyes:'))
if "d" in text:
print(emoji.emojize(':grinning_squinting_face:'))
if "e" in text:
print(emoji.emojize(':grinning_face_with_sweat:'))
if "f" in text:
print(emoji.emojize(':rolling_on_the_floor_laughing:'))
if "g" in text:
print(emoji.emojize(':face_with_tears_of_joy:'))
if "h" in text:
print(emoji.emojize(':slightly_smiling_face:'))
if "i" in text:
print(emoji.emojize(':upside-down_face:'))
if "j" in text:
print(emoji.emojize(':winking_face:'))
if "k" in text:
print(emoji.emojize(':smiling_face_with_smiling_eyes:'))
if "l" in text:
print(emoji.emojize(':smiling_face_with_halo:'))
if "m" in text:
print(emoji.emojize(':smiling_face_with_hearts:'))
if "n" in text:
print(emoji.emojize(':smiling_face_with_heart-eyes:'))
if "o" in text:
print(emoji.emojize(':star-struck:'))
if "p" in text:
print(emoji.emojize(':face_blowing_a_kiss:'))
if "q" in text:
print(emoji.emojize(':kissing_face:'))
if "r" in text:
print(emoji.emojize(':grinning_face:'))
if "s" in text:
print(emoji.emojize(':smiling_face:'))
if "t" in text:
print(emoji.emojize(':kissing_face_with_closed_eyes:'))
if "u" in text:
print(emoji.emojize(':kissing_face_with_smiling_eyes:'))
if "v" in text:
print(emoji.emojize(':face_savoring_food:'))
if "w" in text:
print(emoji.emojize(':face_with_tongue:'))
if "x" in text:
print(emoji.emojize(':winking_face_with_tongue:'))
if "y" in text:
print(emoji.emojize(':squinting_face_with_tongue:'))
if "z" in text:
print(emoji.emojize(':money-mouth_face:'))
Put your letter: emoji mapping into a dict:
emoji_map = {
"a": ':grinning_face:',
"b": ':grinning_face_with_smiling_eyes:',
# etc
}
and then you can easily reformat your output, add new mappings, etc without having to change a bunch of individual if statements. For example, to put everything on one line:
print("Enter text to be encoded Here:")
text = input()
print(''.join(emoji_map.get(c.lower(), '') for c in text))
The print() function always prints on a new line. You want to create a variable to take in all of the emojis, then print only once. If you are dealing with strings, for example, append to the strings.
emojis_to_output = ''
if "a" in text:
emojis_to_output += emoji.emojize(':grinning_face:')
# ... and so on ...
if "z" in text:
emojis_to_output += emoji.emojize(':money-mouth_face:')
print(emojis_to_output)
A thing that I haven't seen any answers say is the print function's end argument:
print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)
Print objects to the text stream file, separated by sep and followed by end. sep, end, file and flush, if present, must be given as keyword arguments.
So, for each of your print statements, you could do this:
print(emoji.emojize(':grinning_face:'), end="")
However, you are doing a lot - and I mean a lot - of unnecessary hard coding. Instead of having 26 if statements, just make a dictionary with all your values!
emojis = {
"a": ":grinning_face:",
"b": ":grinning_face_with_smiling_eyes:",
# ... and on and on ...
}
for key in emojis:
if key in text:
print(emoji.emojize(emojis[key]), end="")
print() # Add a final new line
Or, you could even make this a one-liner!
print("".join(key in text and emoji.emojize(emojis.get(key)) for key in emojis))

Is there a different way that I could display my tables based on my arguments entered using the argparse module?

The goal is to display tables based on arguments entered in the terminal.
I've tried to create a function that would output each individual table using if, elif and else statements but that would only display the tables individually.
I've also tried a different way which is preferred and it would add a column to my table based on my arguments.
def generate_table(inventory):
args = arguments()
data = generate_data(inventory)
main_headers = ['os_version', 'serial_number']
lldp_headers = ['lldp']
out_file = ['outfile']
main_header = []
lldp_header = []
main_table_header = PrettyTable()
lldp_table_header = PrettyTable()
for arg in vars(args):
if arg in main_headers and getattr(args, arg):
main_header.append(arg)
elif arg in lldp_headers and getattr(args, arg):
lldp_header.append(arg)
elif arg in out_file and getattr(args, arg):
out_file.append(arg)
output_file(inventory)
main_header.insert(0, 'Hostname')
main_table_header.field_names = main_header
lldp_table_header.field_names = ['Hostname', 'Neighbor', 'Local Interface', 'Neighbor Interface']
for hostname, details in data.items():
row = [hostname]
for column in main_table_header.field_names[1:]:
row.append(details[column])
main_table_header.add_row(row)
for lldp_data in details['lldp']:
neighbor = lldp_data['device-id']
local_int = lldp_data['local-interface']
neigh_int = lldp_data['connecting-interface']
lldp_table_header.add_row([hostname, neighbor, local_int, neigh_int])
print(main_table_header)
print(lldp_table_header)
def arguments():
parser = argparse.ArgumentParser(description='Argparse for Training Course.')
parser.add_argument('-s', '--serial_number', action='store_true', help='Device Serial Numbers')
parser.add_argument('-v', '--os_version', action='store_true', help='Output Devices OS')
parser.add_argument('--lldp', action='store_true', help='Output LLDP Data')
parser.add_argument('--outfile', action='store_true', help='Output to file')
parser.add_argument('--inventory', help='Inventory File', default=["inventory.yml"], required=True)
args = parser.parse_args()
return args
def get_inventory(inventory):
with open(inventory) as fh:
yml_file = yaml.load(fh)
return yml_file
def main():
args = arguments()
if not os.path.isfile(args.inventory):
sys.exit('Please specify valid, readable YAML file with data')
inventory = get_inventory(args.inventory)
generate_table(inventory)
if __name__ == '__main__':
main()
YAML FILE:
csr1:
username: admin
password: pass
transport: restconf
csr2:
username: admin
password: pass
transport: restconf
This is what I expect:
python3 rest5.py --inventory inventory.yml -v
+----------+------------+
| Hostname | os_version |
+----------+------------+
| csr1 | 16.6 |
| csr2 | 16.6 |
+----------+------------+
python3 rest5.py --inventory inventory.yml -s
+----------+---------------+
| Hostname | serial_number |
+----------+---------------+
| csr1 | 9KIBQAQ3OPE |
| csr2 | 9KIBQAQ3OPE |
+----------+---------------+
python3 rest5.py --inventory inventory.yml -s -v
+----------+---------------+------------+
| Hostname | serial_number | os_version |
+----------+---------------+------------+
| csr1 | 9KIBQAQ3OPE | 16.6 |
| csr2 | 9KIBQAQ3OPE | 16.6 |
+----------+---------------+------------+
python3 rest5.py --inventory inventory.yml --lldp
+----------+--------------+-----------------+--------------------+
| Hostname | Neighbor | Local Interface | Neighbor Interface |
+----------+--------------+-----------------+--------------------+
| csr1 | csr2.com | Gi1 | Gi1 |
| csr2 | csr1.com | Gi1 | Gi1 |
+----------+--------------+-----------------+--------------------+
python3 rest5.py --inventory inventory.yml --lldp -s -v
+----------+---------------+------------+
| Hostname | serial_number | os_version |
+----------+---------------+------------+
| csr1 | 9KIBQAQ3OPE | 16.6 |
| csr2 | 9KIBQAQ3OPE | 16.6 |
+----------+---------------+------------+
+----------+--------------+-----------------+--------------------+
| Hostname | Neighbor | Local Interface | Neighbor Interface |
+----------+--------------+-----------------+--------------------+
| csr1 | csr2.com | Gi1 | Gi1 |
| csr2 | csr1.com | Gi1 | Gi1 |
+----------+--------------+-----------------+--------------------+
The actual output:
python3 rest5.py --inventory inventory.yml -s
+----------+---------------+
| Hostname | serial_number |
+----------+---------------+
| csr1 | 9KIBQAQ3OPE |
| csr2 | 9KIBQAQ3OPE |
+----------+---------------+
+----------+--------------+-----------------+--------------------+
| Hostname | Neighbor | Local Interface | Neighbor Interface |
+----------+--------------+-----------------+--------------------+
| csr1 | csr2.com | Gi1 | Gi1 |
| csr2 | csr1.com | Gi1 | Gi1 |
+----------+--------------+-----------------+--------------------+
python3 rest5.py --inventory inventory.yml --lldp
+----------+
| Hostname |
+----------+
| csr1 |
| csr2 |
+----------+
+----------+--------------+-----------------+--------------------+
| Hostname | Neighbor | Local Interface | Neighbor Interface |
+----------+--------------+-----------------+--------------------+
| csr1 | csr2.com | Gi1 | Gi1 |
| csr2 | csr1.com | Gi1 | Gi1 |
+----------+--------------+-----------------+--------------------+
Your generate_table method is always printing out two tables, when you only want it to print out one:
Your original function:
def generate_table(inventory):
args = arguments()
...
print(main_table_header)
print(lldp_table_header)
Should simply change to:
def generate_table(inventory):
args = arguments()
...
if args.lldp:
print(lldp_table_header)
else:
print(main_table_header)
Other commenters mentioned optimizations that would generally make the code better which you should consider implementing, such as:
only generating arguments once
create only the tables you're going to render instead of running through the motions of creating tables that you aren't going to print in the end
But at the end of the day, you were just a few lines away from making your use cases stated above work the way you wanted them to.
def main():
args = arguments()
if not os.path.isfile(args.inventory):
sys.exit('Please specify valid, readable YAML file with data')
inventory = get_inventory(args.inventory)
generate_table(inventory, args)
You call get_inventory with a string, a values from args. You should also call generate_table with values from args, or args itself. Reevaluating args works, but just makes your code messier.
def generate_table(inventory, args):
# args = arguments() # no need to reevaluate args
data = generate_data(inventory)
...
Same could be done for output_file, though it isn't obvious where you are using args.
In generate_table you appear to use args mainly in:
for arg in vars(args):
if arg in main_headers and getattr(args, arg):
main_header.append(arg)
elif arg in lldp_headers and getattr(args, arg):
lldp_header.append(arg)
elif arg in out_file and getattr(args, arg):
out_file.append(arg)
output_file(inventory)
That's an obscure piece of code, treating args both as Namespace and dictionary. I think it's just checking on the values of
args.os_version
args.serial_number
args.lldp
args.outfile
Those are all store_true, so they will always be present, and a True/False value. So you could
if args.out_file:
output_file(inventory)
if args.lldp:
lldp_header.append('lldp')
But I'm not too interested in digging through all the logic steps.
Make sure that you understand what parse_args has produced. During debugging I encourage users to
print(args)
That way there'll be fewer surprises.

Tornado long polling requests

Below is the most simple example of my issue:
When a request is made it will print Request via GET <__main__.MainHandler object at 0x104041e10> and then the request will remain open. Good! However, when you make another request it does not call the MainHandler.get method until the first connection has finished.
How can I get multiple requests into the get method while having them remain long-polling. I'm passing arguments with each request that will get different results from a pub/sub via redis. Issue is that I only get one connection in at a time. Whats wrong? And why is this blocking other requests?
import tornado.ioloop
import tornado.web
import os
class MainHandler(tornado.web.RequestHandler):
#tornado.web.asynchronous
def get(self):
print 'Request via GET', self
if __name__ == '__main__':
application = tornado.web.Application([
(r"/", MainHandler)])
try:
application.listen(int(os.environ.get('PORT', 5000)))
tornado.ioloop.IOLoop.instance().start()
except KeyboardInterrupt:
tornado.ioloop.IOLoop.instance().stop()
Diagram Left: As described in issue above. The requests are not handled in the fashion requested in right diagram.
Diagram on the right I need the requests (a-d) to be handled by the RequestHandler and then wait for the pub/sub to announce their data.
a b c d
+ + + + ++ a b c d
| | | | || + + + +
| | | | || | | | |
| | | | || | | | |
| | | | || | | | |
| v v v || | | | |
+---|-----------------------------+ || +-----|----|---|---|------------------+
| | | || | | | | | |
| + RequestHandler| || | + + + + RequestHan. |
| | | || | | | | | |
+---|-----------------------------+ || +-----|----|---|---|------------------+
+---|-----------------------------+ || +-----|----|---|---|------------------+
| | | || | | | | | |
| + Sub/Pub Que | || | v + v v Que |
| | | || | | |
+---|-----------------------------+ || +----------|--------------------------+
+---|-----------------------------+ || +----------|--------------------------+
| || |
| Finished || | Finished
v || v
||
||
||
||
||
||
||
++
If this is accomplishable with another programming language please let me know.
Thank you for your help!
From http://www.tornadoweb.org/en/stable/web.html#tornado.web.asynchronous:
tornado.web.asynchronous(method)
...
If this decorator is given, the response is not finished when the
method returns. It is up to the request handler to call self.finish()
to finish the HTTP request. Without this decorator, the request is
automatically finished when the get() or post() method returns.
You have to finish get method explicitly:
import tornado.ioloop
import tornado.web
import tornado.options
from tornado.options import define, options
define("port", default=8000, help="run on the given port", type=int)
class MainHandler(tornado.web.RequestHandler):
#tornado.web.asynchronous
def get(self):
print 'Request via GET', self
self.finish()
if __name__ == '__main__':
application = tornado.web.Application([
(r"/", MainHandler)])
try:
application.listen(options.port)
tornado.ioloop.IOLoop.instance().start()
except KeyboardInterrupt:
tornado.ioloop.IOLoop.instance().stop()

Categories

Resources