473,659 Members | 2,965 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

namespace/dictionary quandry


I have been delegated to produce a tool that has
python embedded in it. The desire is to have a
command line interface that inherits all the python
scripting functionality so people can use the tool
either with a flat commandline entry like you would
a debugger or with a script using scoping, loops and
conditional.

I am going from knowing nothing about python to
almost nothing so the learning curve is rather
steep at this point.

I have a dummy program that inherits code.Interactiv eConsole
functionality. I can grab each input line and scan it for
commands that match my tool's syntax ("attach") and if it
does, I change the line to reflect a python legal function
call associated with that commond (DoAttach) and from there
do what I want with the line. The actual input lines are
executed with a self.push() call.

The problem I have is in timely symbol resolution. I really
want to run eval() on each of the arguments at the time
the DoAttach() function is executed, but don't know how
and where from does one get the dictionary with the proper
name space. If I run eval at the time of initial reading
of the input it works for flat first level input, but not
for nested scoping:

cli.py
bosco=5
if 1:
attach bosco
bosco=7
attach bosco

attach bosco

This will result in:
bosco=5
if 1: ... attach bosco
... bosco=7
... attach bosco
...
DoAttach: ['5']
DoAttach: ['5'] <--- WRONG (at least, not what I want) attach bosco

DoAttach: ['7']

How does one export the correct dictionary?

Attached is the toy program that creates this output.

Keep in mind that I am probably aproaching this all
wrong. Any relevant suggestions would be most appreciated,

Jack

*************** **
File cli.py:
*************** **
#!/usr/bin/env python

import myparse

cli = myparse.CLI(glo bals())
cli.interact()
*************** **
File myparse.py:
*************** **
import code
import re
import string
import sys

def DoAttach(args):
print "DoAttach:" , args
pass
class CLI(code.Intera ctiveConsole):
"""Simple test of a Python interpreter augmented with custom
commands."""

commands = { \
"attach" : "DoAttach"
}

def __init__(self, locals = None):

# Call super-class initializer
code.Interactiv eConsole.__init __(self, locals, "<console>" )

# Compile regular expression for finding commmands
self.regexp = re.compile('[a-z]*')
def interact(self):

my_dictionary = self.locals

# Set the primary and secondary prompts
sys.ps1 = ">>> "
sys.ps2 = "... "

# Input Loop
is_more = 0
bosco = 0
while 1:
try :
# Display the appropriate prompt
if not sys.stdin.isatt y():
prompt = ""
elif is_more:
prompt = sys.ps2
else:
prompt = sys.ps1

# Read the next line of input
#self.write("in teract 1\n")
line = self.raw_input( prompt)

# TODO: add logging of input line here...

# Process complete lines
if 1:
line = self.process(li ne)

# Push incomplete lines onto input stack
if line or is_more:
is_more = self.push(line)

# Handle CTRL-C
except KeyboardInterru pt:
self.write("\nK eyboardInterrup t\n")
is_more = 0
self.resetbuffe r()

# Handle CTRL-D
except EOFError:
self.write("\n" )
is_more = 0
self.resetbuffe r()
raise SystemExit
def process(parent, line):

# Attempt to match line against our command regular expression

temp_line = string.lstrip(l ine)
len_1 = len(line)
len_2 = len(temp_line)
white_spaces = len_1-len_2
if white_spaces is not 0:
front_padding = line[0:white_spaces]

match = parent.regexp.m atch(temp_line)
if match is not None:

# Extract the command and argument strings
cmd_string = match.group()
arg_string = string.lstrip(t emp_line[match.end():])

# Find the function for this command in the command
dictionary
function = parent.commands .get(cmd_string )

if function is not None:

# Split argument string into individual arguments
args = string.split(ar g_string)

# Recursively evaluate all arguments
i = 0
while i < len(args):
try:

# Grab value and position of this argument
unevaluated, pos, i = args[i], i, i + 1

# Have Python attempt evaluation of the argument

evaluated = eval(unevaluate d, parent.locals)

# Did the evaluation produce a "new" result?
if str(evaluated) != str(unevaluated ):

# Place the evaluation in the argument list
args = args[:pos] + \
string.split(st r(evaluated)) + \
args[pos + 1:]

# Go back to the beginning of the argument
list
i = 0

except (SyntaxError, NameError):
pass

# Convert to Python function-call syntax for this
command
line = "myparse." + function + "(" + str(args) + ")"
if white_spaces is not 0:
line = front_padding + line

# Return the line to be processed by Python
return line


Jul 18 '05 #1
8 1893
Jack Carter wrote:
This will result in:
>>> bosco=5
>>> if 1: ... attach bosco
... bosco=7
... attach bosco
...
DoAttach: ['5']
DoAttach: ['5'] <--- WRONG (at least, not what I want) >>> attach bosco

DoAttach: ['7']


The suite

attach bosco
bosco = 7
attach bosco

is only executed after the final empty line. Therefore any access to the
right dictionary in the process() method will give you the current value
bosco==5 which is not what you want.
You are in effect translating the suite into (simplified)

DoAttach(5)
bosco = 7
DoAttach(5) # the previous line has not yet been executed

I think the easiest way to get the desired effect ("late binding") is like
so:

def process(self, line):
temp_line = line.lstrip()
front_padding = line[:len(line)-len(temp_line)]

match = self.regexp.mat ch(temp_line)
if match:
line = front_padding + "myparse.DoAtta ch(bosco)"

return line

I. e. change the generated line to contain variable names instead of values
and leave the resolution to python. (You hint you don't wont that either.
Why?)

By the way, I wasn't able to run your code - the indentation is seriously
messed up. I recommend you ensure a 4-space indentation in all code you
currently have before you move on. That will spare you a lot of trouble
later on.

Another minor issue: 'value is 0' may or may not work depending on the
python implementation ('value is 1000' won't work even in current CPython).
With 'value == 0' you are on the safe side.

Peter

Jul 18 '05 #2
Peter,

I guess I just don't understand.

Basically this is to go into a tool that accepts
commandline arguments, one at a time, but will also
allow scripting for testing purposes. Thus the desire
to leverage off python for the commandline interface,
but not for the whole program.

The input from the user will be either from the console or
read from a command file. A simple example of what could
be entered is:

bosco=5
if 1:
print bosco
attach bosco 9
bosco=7
print bosco
attach bosco 9

The result I would expect would be for my DoAttach()
routine to receive the python evaluated value of each
of the arguments leaving the ones that it doesn't understand
alone. Whether this happens automagically or by hand I don't
care as long as I get what right value.

In the above trying to follow your advice, remembering that
at this stage of the game I am probably missing the point, this
is the result I expect:

johmar % demo.py
bosco=5
if 1: .... print bosco
.... attach bosco 9
.... bosco=7
.... print bosco
.... attach bosco 9
....
5
DoAttach: [5, 9]
7
DoAttach: [7, 9]

This is what I get:

johmar % demo.py bosco=5
if 1:

.... print bosco
.... attach bosco 9
.... bosco=7
.... print bosco
.... attach bosco 9
....
5
DoAttach: ['bosco', '9']
7
DoAttach: ['bosco', '9']

Now I realize that this is probably due to the fact that
I have the lines:

if white_spaces:
line = front_padding + "myparse." + function + "(" +
str(args) + ")"
else :
line = "myparse." + function + "(" + str(args) + ")"

which put make the arguments strings, but that is because I don't
know how to appropriately pack the "line" for later parsing. Maybe
that is the crux of my problem. Remember, there will be many commands
for my tool and the arguments will be variable length and this code
will not know what variables the gentle use would use.

Here is the simplified code with hopefully the tabs expanded
base on your earlier input. Hopefully you'll see the obvious
error of my way and point it out.

Thanks ever so much,

Jack

*************** *************** ****
demo.py
*************** *************** ****
#!/usr/bin/env python

import myparse

cli = myparse.CLI(glo bals())
cli.interact()

*************** *************** ****
myparse.py
*************** *************** ****
import code
import re
import string
import sys

############### ############### ############### ############### ############### #####
#
# DoAttach
#
# Dummy function that I will eventually use to do
# real stuff.
#
############### ############### ############### ############### ############### #####
def DoAttach(args):

print "DoAttach:" , args
pass
class CLI(code.Intera ctiveConsole):
"""Simple test of a Python interpreter augmented with custom commands."""

commands = { \
"attach" : "DoAttach"
}

def __init__(self, locals = None):

# Call super-class initializer
code.Interactiv eConsole.__init __(self, locals, "<console>" )

# Compile regular expression for finding commmands
self.regexp = re.compile('[a-z]*')
############### ############### ############### ############### ######
#
# interact
#
# This will read and process input lines from within
# my main application as though on a python commandline.
#
############### ############### ############### ############### ######
def interact(self):

# Set the primary and secondary prompts
sys.ps1 = ">>> "
sys.ps2 = "... "

# Input Loop
is_more = 0
bosco = 0
while 1:
try :
# Display the appropriate prompt
if not sys.stdin.isatt y():
prompt = ""
elif is_more:
prompt = sys.ps2
else:
prompt = sys.ps1

# Read the next line of input
#self.write("in teract 1\n")
line = self.raw_input( prompt)

# TODO: add logging of input line here...

# Process complete lines
if 1:
line = self.process(li ne)

# Push incomplete lines onto input stack
if line or is_more:
is_more = self.push(line)

# Handle CTRL-C
except KeyboardInterru pt:
self.write("\nK eyboardInterrup t\n")
is_more = 0
self.resetbuffe r()

# Handle CTRL-D
except EOFError:
self.write("\n" )
is_more = 0
self.resetbuffe r()
raise SystemExit

############### ############### ############### ############### ######
#
# process
#
# This will determine if the input command is either
# from my application's command language or a python
# construct.
#
############### ############### ############### ############### ######
def process(parent, line):

# Attempt to match line against our command regular expression

temp_line = string.lstrip(l ine)
len_1 = len(line)
len_2 = len(temp_line)

white_spaces = len_1-len_2
if white_spaces:
front_padding = line[0:white_spaces]

match = parent.regexp.m atch(temp_line)
if match is not None:

#parent.write(" process 1\n")
# Extract the command and argument strings
cmd_string = match.group()
arg_string = string.lstrip(t emp_line[match.end():])

# Find the function for this command in the command dictionary
function = parent.commands .get(cmd_string )

if function is not None:

# Split argument string into individual arguments
args = string.split(ar g_string)

# Convert to Python function-call syntax for this command
if white_spaces:
line = front_padding + "myparse." + function + "(" +
str(args) + ")"
else :
line = "myparse." + function + "(" + str(args) + ")"

# Return the line to be processed by Python
return line

Jul 18 '05 #3
Peter,

Actually although your solution is a good one, it won't
really help me because of the nature of our command language.

We have commands in the form of:

result = <command_name > <filename> -e <experiment_nam e>

I currently scan ahead for <command_name > and could do so for
the rest to prevent them from being evaluated by python by
packing them with quotes and then unpacking them later. The
problem lies in the case where the name being used in the
commandline may or may not be a formal name such as a filename
or may be a variable that will evaluate into a filename.

This will be used in a list of filenames or a list of experiment
names iterated through a for loop.
for name in (['file1','file2' ,'file3']): .... expClose name
....
expClose: ['file1']
expClose: ['file2']
expClose: ['file3']

But when the user tries to use a formal name that is
not through a python variable he/she hits an undefine
name error:
expClose file4

Traceback (most recent call last):
File "<console>" , line 1, in ?
NameError: name 'file4' is not defined

If I prescan the <filename> and pack it with quotes I
lose the python evaluation of the name.

The same problem will occur with all my other option arguments
for which there are many.

The solution it would seem would be to do the evaluation
later within the called function. That way I could assume
that all failed eval()'ed names are literals meant for my
command and not a python variable/name.

If this makes sense, the problem I need to solve is how to
deliver the correct namespace dictionary to the called function
so I can invoke eval with it.

Does this make sense?

Regards,

Jack
Jul 18 '05 #4
Jack Carter <jc*****@johmar .engr.sgi.com> wrote:
...
The solution it would seem would be to do the evaluation
later within the called function. That way I could assume
that all failed eval()'ed names are literals meant for my
command and not a python variable/name.

If this makes sense, the problem I need to solve is how to
deliver the correct namespace dictionary to the called function
so I can invoke eval with it.

Does this make sense?


Not very, but then I didn't follow the previous LONG posts on this
thread, so I'll just answer this specific question and hope it helps.
I'll assume the known variable-names are in some dictionary (such as a
locals() or globals() or vars(something) ):

class WeirdNamespace:
def __init__(self, d): self.d = d
def __getitem__(sel f, n): return self.d.get(n,re pr(n))

voila: if n is a key in dict d, this returns the corresponding value,
otherwise it returns n suitably quoted. Just pass to eval a
WeirdNamespace( d) rather than the bare d.

It appears to me your user interface is courting trouble: if I mispell
'variablename' as 'varaiblename' I end up creating a file I didn't mean
to rather than getting a clean error about unknown variable names. But
I'll assume you know your users better than I do and that they _do_
really desire with all their hearts this unholy confusion between
variables and constants...
Alex
Jul 18 '05 #5
On Sep 22, 7:18pm, Alex Martelli wrote:
Subject: Re: namespace/dictionary quandry
Jack Carter <jc*****@johmar .engr.sgi.com> wrote:
...
The solution it would seem would be to do the evaluation
later within the called function. That way I could assume
that all failed eval()'ed names are literals meant for my
command and not a python variable/name.

If this makes sense, the problem I need to solve is how to
deliver the correct namespace dictionary to the called function
so I can invoke eval with it.

Does this make sense?
Not very, but then I didn't follow the previous LONG posts on this


Alex,

The length was really taken up with a testcase to make
the problem less hand wavey.
thread, so I'll just answer this specific question and hope it helps.
I'll assume the known variable-names are in some dictionary (such as a
locals() or globals() or vars(something) ):

class WeirdNamespace:
def __init__(self, d): self.d = d
def __getitem__(sel f, n): return self.d.get(n,re pr(n))
So, how and or where does this fit in with my example?
Does both the call to the function where I want to do
the eval() and self.push(line) command have to be in the
same namespace and or file for this to work?

voila: if n is a key in dict d, this returns the corresponding value,
otherwise it returns n suitably quoted. Just pass to eval a
WeirdNamespace( d) rather than the bare d.

It appears to me your user interface is courting trouble: if I mispell
'variablename' as 'varaiblename' I end up creating a file I didn't mean
to rather than getting a clean error about unknown variable names. But
I'll assume you know your users better than I do and that they _do_
really desire with all their hearts this unholy confusion between
variables and constants...


This is driven by customers that who want both a type-in command
language and a variant using all the power of python for test
scripting purposes. If you misspell something and there is the
possibility of it screwing something up that we can't tell either
in the parser or downstream in the backend of the tool, well that's
life in the big city.

Thanks,

Jack
Jul 18 '05 #6
Jack Carter wrote:
class WeirdNamespace:
def __init__(self, d): self.d = d
def __getitem__(sel f, n): return self.d.get(n,re pr(n))


So, how and or where does this fit in with my example?
Does both the call to the function where I want to do
the eval() and self.push(line) command have to be in the
same namespace and or file for this to work?


I use a slight variation of Alex' suggestion:

class Locals(dict):
def __getitem__(sel f, name):
try:
return dict.__getitem_ _(self, name)
except KeyError:
return name

class CLI(code.Intera ctiveConsole):
"""Simple test of a Python interpreter augmented with custom
commands."""

commands = { \
"attach" : "DoAttach"
}

def __init__(self, locals = None):

# Call super-class initializer
code.Interactiv eConsole.__init __(self, locals, "<console>" )
self.locals = Locals(self.loc als)

# Compile regular expression for finding commmands
self.regexp = re.compile('[a-z]*')

[The rest of the code is the same as in my previous post]

Now try it:
for name in "abc":

fed to the snake: for name in "abc":
.... attach name
fed to the snake: myparse.DoAttac h([name])
.... attach noname
fed to the snake: myparse.DoAttac h([noname])
....
fed to the snake:
DoAttach: ['a']
DoAttach: ['noname']
DoAttach: ['b']
DoAttach: ['noname']
DoAttach: ['c']
DoAttach: ['noname']

Unfortunately this will only work with Python 2.4.

Here's a solution that might work for 2.3:

[Does not require the above modifications]

def process(self, line):
indent = line.lstrip()
# Attempt to match line against our command regular expression

temp_line = string.lstrip(l ine)
len_1 = len(line)
len_2 = len(temp_line)

white_spaces = len_1-len_2
if white_spaces:
front_padding = line[0:white_spaces]

match = self.regexp.mat ch(temp_line)
if match is not None:

#self.write("pr ocess 1\n")
# Extract the command and argument strings
cmd_string = match.group()
arg_string = string.lstrip(t emp_line[match.end():])

# Find the function for this command in the command dictionary
function = self.commands.g et(cmd_string)

if function is not None:

args = parseArgs(arg_s tring)
for arg in args:
if arg not in self.locals:
self.locals[arg] = arg
line = makePythonCall( "myparse." + function, args)
if white_spaces:
line = front_padding + line
print "fed to the snake:", line

# Return the line to be processed by Python
return line

I just ensure that all arguments not already in self.locals are added with
their name as their value. (I also renamed 'parent' to 'self' - I could not
stand it any longer :-)

Note that I don't particularly like both hacks and would rather use plain
old python functions with standard python syntax instead of your custom
language.
Peter


Jul 18 '05 #7
Jack Carter <jc*****@johmar .engr.sgi.com> wrote:
...
later within the called function. That way I could assume
that all failed eval()'ed names are literals meant for my
command and not a python variable/name.
...
The length was really taken up with a testcase to make
the problem less hand wavey.


If you can't make a shorter example, I'm not gonna make time to study
that one, sorry.

I'll assume the known variable-names are in some dictionary (such as a
locals() or globals() or vars(something) ):

class WeirdNamespace:
def __init__(self, d): self.d = d
def __getitem__(sel f, n): return self.d.get(n,re pr(n))


So, how and or where does this fit in with my example?
Does both the call to the function where I want to do
the eval() and self.push(line) command have to be in the
same namespace and or file for this to work?


All it does is implement what you asked: make a mapping that assumes all
unknown variable names are to be taken as literals, starting from a
mapping of all 'known variable names' to their values.

I'll assume you know your users better than I do and that they _do_
really desire with all their hearts this unholy confusion between
variables and constants...


This is driven by customers that who want both a type-in command
language and a variant using all the power of python for test
scripting purposes. If you misspell something and there is the
possibility of it screwing something up that we can't tell either
in the parser or downstream in the backend of the tool, well that's
life in the big city.


I suspect the first time your users want to use a file named 'for'
they'll scream bloody murder, but hopefully that won't happen before
they've paid you enough for you to retire in comfort to a nice
Carribbean island without extradition treaties, so, cheer up.
Alex
Jul 18 '05 #8
On Sep 22, 8:48pm, Peter Otten wrote:
Subject: Re: namespace/dictionary quandry I just ensure that all arguments not already in self.locals are added with
their name as their value. (I also renamed 'parent' to 'self' - I could not
stand it any longer :-)
Novice error on my part. Thanks for the correction.

Note that I don't particularly like both hacks and would rather use plain
old python functions with standard python syntax instead of your custom
language.
It makes the programmers job easier, but not the customer
who may just want a non-gui debugger commandline session tool.
That customer doesn't want to know anything about python or
function calls even though underneath the covers that's what
they are getting. At the same time, the testers want the full
scripting power of python.

To make life even more fun, there is a C++ front end and C++
back end that deal with many processes over many nodes. Some
of the commands are syncronous and return a value that feed
into the python name space and others are asyncronous that
may implode somewhere in the future and need to bring the
whole mess to some sane state to handle the problem

I guess it is my own private hell to work on.

Your change seems to work great!

Thanks,

Jack

Peter

Jul 18 '05 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
1357
by: Doug Rosser | last post by:
I'm writing a fairly complicated test framework and keeping configuration data inside ini files that are parsed at runtime by the ConfigParser module. For example, there would be a section similar to the following server1:{'hostname':'alpha','os':'posix'} server2:{'hostname':'beta','os':'win'}
8
2070
by: Elaine Jackson | last post by:
I would like to be able to write a function f, which will live in a module M, and will call a function g, such that, when f is imported from M into the interpreter, and invoked there, its invokation of g will return the interpreter's global namespace. Is there a way to do this and, if so, how? Muchas gracias for any and all assistance. Peace
13
1637
by: David Rysdam | last post by:
Getting no answer yesterday, I've done some investigation and I obviously don't understand how python namespaces work. Here's a test program: #!/usr/bin/python b = 2 def sumWithGlobal(a): return a + b
8
3854
by: Bo Peng | last post by:
Dear list, I am writing a Python extension module that needs a way to expose pieces of a big C array to python. Currently, I am using NumPy like the following: PyObject* res = PyArray_FromDimsAndData(1, int*dim, PyArray_DOUBLE, char*buf); Users will get a Numeric Array object and can change its values (and actually change the underlying C array).
31
2686
by: Bo Peng | last post by:
Dear list, I have many dictionaries with the same set of keys and I would like to write a function to calculate something based on these values. For example, I have a = {'x':1, 'y':2} b = {'x':3, 'y':3} def fun(dict):
27
2091
by: Ron Adam | last post by:
Hi, I found the following to be a useful way to access arguments after they are passed to a function that collects them with **kwds. class namespace(dict): def __getattr__(self, name): return self.__getitem__(name) def __setattr__(self, name, value): self.__setitem__(name, value) def __delattr__(self, name):
4
1006
by: Petr Jakes | last post by:
In my code I have relatively wide dictionary definition (about 100 rows). I would like to put it in to the different file (module) because of the main code readability (say the name of the file will be "my_dictionary.py") In the dictionary I have strings formatted using % operator like: lcd={2:"Your credit= %3d" % (credit)}
0
903
by: David | last post by:
Hi, I'm working on a project where we're juggling with two potential implementations. In the two scenarios, we create objects in the base namespace. These objects are interdependent, in the sense that to compute something, they have to look up the value of the other objects (their parents). The objects are functions, by the way, with some additional attributes. In the first scenario, as the objects are created, they immediately
22
3911
by: Luna Moon | last post by:
I am reading the book "C++ Annotations", and here is a quote from the book: Namespaces can be defined without a name. Such a namespace is anonymous and it restricts the visibility of the defined entities to the source file in which the anonymous namespace is defined. Entities defined in the anonymous namespace are comparable to C’s static functions and variables. In C++ the static keyword can still be used, but its use is more
0
8335
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8851
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8747
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
8627
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7356
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6179
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5649
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4175
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4335
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.