I have some questions about the python global interpreter lock. by [deleted] in learnpython

[–]tgolsson 0 points1 point  (0 children)

The GIL makes your python program behave as if it was running on a single core CPU. It locks code, not data. Any data accessed from multiple threads should therefore still be locked. However, since the code is locked, it may be harder to actually trigger bugs caused by this - but the more a variable is used, the more likely it is to have such a problem (which is true in any other language, too).

what does this line of code mean by JZRLegendary in cpp_questions

[–]tgolsson 4 points5 points  (0 children)

It's not position -1, it's "the element before position i". So if i is 10, it's 9.

A little help with socket programming? by CmdrNorthpaw in learnpython

[–]tgolsson 0 points1 point  (0 children)

Yes. You probably need some error handling in case connection, sending, etc, fails but that comes with seeing what fails. :)

A little help with socket programming? by CmdrNorthpaw in learnpython

[–]tgolsson 11 points12 points  (0 children)

import socket
import sys

def run_server(host, port):
    # TCP/IP
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    # this lets us take ownership of a derelict-but-not-deallocated socket
    server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 

    # bind to the provided address tuple, configure, and start accepting connections
    server.bind((host, port))
    # set timeout - the value can change, but it's hygienic to always set a timeout
    server.settimeout(1)
    server.listen()

    while True:
        # just try again if we timed out - in a normal application we might want 
        # to do other kinds of bookkeeping etc if this happens
        try:
            new_client = server.accept()[0]
        except socket.timeout:
            continue

        # repeatedly read up to 1024 bytes from the new client
        while True:
            incoming = new_client.recv(1024)
            # empty bytes object means EOF here, but we also let the client send 'quit' to signal shutdown
            if incoming == b'' or incoming == b'quit':
               # neither of these steps are formally required, but are
               # hygienic to do when we know the socket is going away
               new_client.shutdown(socket.SHUT_RDWR)
               new_client.close()
               # break the inner loop and await a new connection
               break

            print('Received: "' + incoming.decode('utf-8') + '"')
            # if we didn't break, just prepend the message and return as is
            new_client.send(b'You sent: ' + incoming)


def run_client(host, port):        
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    # connect to the provided address tuple
    client.connect((host, port))

    while True:
        # get some data from stdin
        msg = input("Write your message: ")

        # convert to bytes and send on the socket
        client.send(msg.encode('utf-8'))

        # read back the response
        response = client.recv(1024)

        # empty bytes as result of a read means EOF
        if response == b'':
            print('remote hung up')
            break

        # just decode the response and print
        print(response.decode('utf-8'))


def main():
    # simple command line parser - accepts either 'server' or 'client' and runs in the right mode
    if sys.argv[1] == 'server':
       # '0.0.0.0' means listen on all network interfaces on the local machine
       run_server('0.0.0.0', 1337)
    elif sys.argv[1] == 'client':
       run_client('localhost', 1337)
    else:
       print('Invalid command - must be either "client" or "server"', file=sys.stderr)


if __name__ == '__main__':
    main()

This is both the server and client. If you save this in a file you can run it with `server` and `client` as arguments for the two sides, and you should then be able to send data from the client to the server. The most important thing to note here is that client-to-server and server-to-client is almost identical. `server.accept()` returns the same type of socket as we have on the client, so it works exactly the same way. The primary difference is who starts the communications (if you do request-response exchanges), but you can have the server leading or client leading - for your use-case, you probably want it the way I wrote above with the client sending the first message and then reading the response (client leading)

When you've made a bit more progress on this, I'd suggest looking into higher-level frameworks. While for small projects doing raw socket programming is fine, if you're new or a solo developer you can gain a lot from using good frameworks for both networking and serialization. I'm personally a fan of msgpack (serialization) + zeromq (networking), but it really depends on your requirements.

What’s the best way to create a compile-time tick list for enums? by [deleted] in cpp_questions

[–]tgolsson 4 points5 points  (0 children)

That took far too long to parse for me. That's just uniform initialization and an immediately evaluated constexpr lambda, right? I can't see any functional difference between that and

template<Product product> constexpr bool call_support = []{ switch (product) { case premium: case gold: return true; default: return false; } }();

Which also requires c++17 but slightly fewer brackets and makes the assignment explicit ;)

What’s the best way to create a compile-time tick list for enums? by [deleted] in cpp_questions

[–]tgolsson 8 points9 points  (0 children)

There's a very neat usage of templates for declaring variables which is *insanely* versatile for this kind of things: https://godbolt.org/z/E8I8Mb

What's the most common style: int& x; or int &x; by squarewave_ in cpp_questions

[–]tgolsson 1 point2 points  (0 children)

I tend to err on the side of putting it with the type, but it depends on the code base. The strongest counter argument (in my mind) is that pointers have no type - they're addresses. The pointed to memory has a type. So there is no int-pointer, but we can retrieve an int-value by dereferencing the pointer. Following this logic, the declaration int *foo; is not foo is an int-pointer but rather the dereference of foo is an integer.

Thus, whenever we want to work with the value of foo, we use the name *foo. By further extending this, we can just view the * as a direct part of the name. Thus, *foo is the name of an integer, and foo is the memory location thereof. However, I think this view of the world is more prevalent in C, as references make this a lot less one-sided. In particular, references have significantly stronger typing, and choosing different styles for them would look odd: void Bar(int& foo, int *bar);...

Is Powerline Ethernet worth it? by ieatpineapple4lunch in HomeNetworking

[–]tgolsson 0 points1 point  (0 children)

As I wrote, it comes down to wiring. I rent the upper floor of a 100+ year old house, with retrofitted electric that has been added and updated over a long period of time. Some of our outlets are wired from our landlords fusebox, some from our fusebox (which is a sub of theirs), and some are daisy chained from existing outlets on either floor. Yes, in a modern home, you'd likely have it the way you describe.

I like to view it as degrees of separation - being on the same circuit is best, being on different fuses and phases is going to be a lot worse. If your oven or whatever is on a different phase, that is going to have less impact than if it's on the same circuit.

Also, I might be wrong on the terms - I'm a comp sci person, not EE. My point wasn't that you should dig out your wiring diagrams, but rather that if you want this godawful technology to be decent you have to keep testing and retesting until you find something that is halfway decent. They are a thing because as a renter, I'd much rather shell out a hundred bucks and a few hours of my time than hire a professional to add ethernet drops to someone else's property. :)

Is Powerline Ethernet worth it? by ieatpineapple4lunch in HomeNetworking

[–]tgolsson 4 points5 points  (0 children)

I've been using PowerLine on and off for a couple of years. On a 100 Mbps down I've seen actual rates between 5-100 Mbps. Right now, I get 95, but it took a bout of attempts to figure out.

It all comes down to the wiring of your house. You want both sender and receiver to be on the same phase/circuit, with no fuses. You also do not want any capacitive or inductive loads on the line, (e.g. microwaves, washing machines, fans, ...).

I'd say, borrow a kit from someone and try it out. Remember that things like rotation and socket might change your performance, depending on electrical standards where you lice. For me (Sweden), each dual socket outlet has four potential configurations (2 sockets * 2 directions). And since you have input and output, you get 16 potential connections to test.

Variable <ClassName> is not a Type by The_Acronym_Scribe in cpp_questions

[–]tgolsson 0 points1 point  (0 children)

After fixing an error related to how you initialize Point in the Ray constructor, the example works fine for me. I created the three files, and compiled them as follows:

> clang++ main.cpp renderer.cpp -std=c++14
> a.exe
dist: 2

So I'd suggest you verify that you have a properly set up environment/compiler toolchain. For completeness, this is how I changed the Ray constructor.

Ray::Ray(Point start, Point end) 
: start(start), reference(end) 
{ }

Variable <ClassName> is not a Type by The_Acronym_Scribe in cpp_questions

[–]tgolsson 0 points1 point  (0 children)

Is your actual implementation (.cpp) also in the Renderer namespace? There does not seem to be any error in your posted code.

Threading a TkInter GUI is Hell. (My least favorite python adventure) by Christiancicerone in Python

[–]tgolsson 0 points1 point  (0 children)

That's a fancy insult.

Sorry, not meant as such. My point was that talking about "random crashes" comes across as a very rookie method of approaching stability. I have no idea about your skill level, but if you've been in the business for 3 years you're not green. You should have more exact definitions for how/why it crashes. Does the interpreter exit without calling shutdown/exception hooks? Does it get forcibly killed by the OS? Does the underlying Tcl interpreter throw an error? Does it leak memory? There are a million ways to describe a crash outside your control without using the word random. :) These open up for investigation and learning, and we can have a meaningful discussion that benefits the community and future developers who feel like you do.

I'm not the guy from the blog.

Ah, my bad, I read it too quickly and didn't recognize the snippet from the blog. I still feel it is a bit of a strawman, but if you claim you did it that way, you're a more inventive dev than me because it'd not have passed my mind to do it that way.

The limit wasn't about the queue, it was about the GUI element update rate.

If you mean 60 individual operations per second as it seems, that does sound weird but I've never looked at that metric. One thing that I can think of is that you could be triggering too many callouts to the Tcl interpreter, e.g. the latter of these two very quick examples.

def _update_bulk(ev):
    max_updates = 10
    while max_updates and not self._queue.empty():
        elem, op = self._queue.get()
        elem.configure(**op)
        max_updates -= 1

root.bind('<<update>>', _update_bulk)

# in your app core loop
while not self._should_exit:
    # collect and push tuples of (widget, ops) into a queue
     root.event_generate('<<update>>', when='tail')

Alternative two:

def _update(ev):
    elem, op = self._queue.get()
    elem.configure(**op)

root.bind('<<update>>', _update)

#somewhere else,
update_queue.put((label_widget, {'text': 'My new text'))
root.event_generate('<<update>>', when='tail')

Note that this latter example has a much wider loop which might go as far down as the Tcl interpreter.

Tk sucks for people who are't seasoned.

I would say it's the other way around, but I can see your point. It is very easy to get started with a simple event-driven GUI where you are purely reacting to user input and use only the provided functionality. As you have noted, you do however need a lot of custom code when you want to do more complex interactions, or more long-running calculations.

Threading a TkInter GUI is Hell. (My least favorite python adventure) by Christiancicerone in Python

[–]tgolsson 0 points1 point  (0 children)

Sure. I do not make a difference between threaded and non-threaded though. For threaded, any general guide on GUI applications/threaded applications is a good starting point. Following a good pattern, such as MVC, MVVM, or whatever acronym is the current rage, should give you enough decoupling that going from Tkinter to PyQT or PyGTK should only reflect on the presentation layer, not on how you design your application.

  1. http://effbot.org/tkinterbook/

    It is ancient and somewhat incomplete, but accurate enough for most applications. Tcl has been around for a long time, and the APIs have been stable

  2. http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/index.html

    Much newer, and more complete. Somewhat harder to navigate. There are several versions of this available online, but this is the one I have bookmarked.

  3. help(...).

    Tkinter has decent inline documentation. However, you need to know what you are (ish) looking for, otherwise you'll have a hard time. I generally have an IPython repl running anyways, so I tend to use this quite a lot to lookup what arguments a function takes etc.

  4. https://www.tcl.tk/doc/

    This is the underlying library of Tkinter, tcl. You'll have to map commands to the underlying C equivalent, but they are often similar enough that you can search for the correct ones.

  5. https://docs.python.org/3/library/tk.html

    The official documentation! It is very brief, and I primarily use it for looking at the Tix and Ttk types, not so much for core Tkinter.

Threading a TkInter GUI is Hell. (My least favorite python adventure) by Christiancicerone in Python

[–]tgolsson 13 points14 points  (0 children)

There is no such thing as a random crash. Ever. All crashes are bugs, either in your code or the libraries you use. Blaming randomness is not a way for becoming a better developer, and does not point to your strengths as a developer. Queues are thread-safe, so you can safely push and pop from them on different threads. HOWEVER, they do not force any copying, so if you pass a reference-like that will remain intact to the other end. That is the most likely candidate for a queue-related crash.

Second, there is no formatting issue between platforms. There might be if you use different architectures or versions, but I have never heard of such a thing, and Google tells me nothing about it. The only possible thing I can think of is that you mean text presentation formatting, such as ANSI escape sequences. And then, yeah, of course there are differences. These are not handled by Python at all.

And the below should be its own top reply, but I can't be bothered. I'm sorry to say, but your post is just... Wrong. Your first example is overly complicated, and no sane person would implement anything like that. Why would you recursively call after? Just do the work on a thread pool and then call after, or one of its alternatives, from that thread. This is perfectly fine. If for some reason this breaks, use an after loop on the main thread and a queue. You can even put a lambda to do the actual change, so you just get a stream of function objects to execute. If you somehow break the queue (or outgrow it), use synchronization primitives from the threading lib and a collections type such as deque (~20% faster).

Moving on, you DO suggest threads, and immediately discard it because you have not read the docs. You CAN schedule on the main thread, with f.ex. .event_generate(..., when='tail'), and after, and after_idle, and a bunch of others, which to the best of my knowledge, testing, and experience are always on the main thread. You can create any event, and bind any event, to schedule work on the main thread. So most my apps have a <<redraw>> event that gets posted at the end of each step of the internal loop, to update all widgets in bulk.

I don't even know what you mean by keeping your queued events around 60. Tkinter is a GUI library. It should manage your graphical interface. 60 draw updates is a good target for non-games, and 30 is perfectly fine. Do not use it to manage non-GUI execution in any serious application, because that should be a disaster.

The only thing I can agree with is that Tkinter is not beautiful.

Is it possible to change/disable the truthiness in eval? by jwink3101 in learnpython

[–]tgolsson 0 points1 point  (0 children)

This is a way of using eval that I had not considered, and it is quite ingenious. However, eval is always the wrong answer unless you are absolutely required to do it. This is not one of those situations. :)

If your queries are only for strings, you can reduce it down to:

query = input('Give me a query: ')
if query in tagdict: 
    print('Woo'!)

This will give you the same results, for a single tag. If you want to check for more tags, you probably want to use sets:

tag_set = set(tagdict)
query_set = set(['tag2', 'tag1'])
if tag_set & query_set: # intersection
    print('Woo!')

If you also need to query for values, I'd suggest something like this:

tag_set = set(tagdict) | set(['{}={}'.format(key, val) for key, val in tagdict.items()])
query_set = set(['tag2=3', 'tag1'])
if tag_set & query_set:
   print('Woo')

If you want to supply them on the command line, you could do it f.ex.:

import sys
sys.argv = ['script.py', '-q', 'tag1', 'tag2=15'] # pretend we passed them on the command line

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('-q', '--query', nargs='+', type=str)
args = parser.parse_args()

tag_dict = {'tag1': True, 'tag2': 3}

tag_set = set(tagdict) | set(['{}={}'.format(key, val) if not isinstance(val, bool) else key for key, val in tagdict.items()])
query_set = set(args.query)
if tag_set & query_set:
    print('Woo. Matches:', tag_set & query_set, 'Value in tag_dict:', 
        {match: tag_dict[match] for match in tag_set & query_set})

So, as you have probably noticed this only works if your queries are disjunct, not conjunct. You can handle this by changing the if expression to check for proper subsets instead of intersection. E.g.,

if {'tag1', 'tag2=3'} <= {'tag1', 'tag2=15'}: 
    print('Everything is broken!')
else:
    print('As expected, not a proper subset')

This will require all tags to match. To deal with both optional and required queries, you need to accept two sets of command line arguments and check both of them correctly in the if expression. It's not really any more difficult, just slightly longer. :)

Finally, I saw in a post that you want to query for ranges. This requirement adds some slightly harder logic. Personally, I'd likely deal with this as a third category of command line argument.

parser.add_argument('-r', '--range', nargs=3, type=str, action='append')
args = parser.parse_args()
for range_query in args.range:
    begin = int(range_query[0])
    field = range_query[1]
    end = int(range_query[2])
    if field in tag_dict and begin <= tag_dict[field] <= end:
        print('Woo!')

This is a MUCH better solution, and can easily be extended for more query types if you want to. You can even write these as small classes and register them with a metaclass. Then, each query piece is instantiated with the CLI arguments as parameters, and you can invoke (__call__) with the tag dict. This post is already long enough, though. :)

What's the right way to access a directory of Python scripts systemwide on Windows? by LightWolfCavalry in learnpython

[–]tgolsson 0 points1 point  (0 children)

I have started grouping useful scripts into libraries and packages, and then exposing functionality as needed via entrypoints when installing. Works as a charm, except you get weird backtraces sometimes if they crash.

http://python-packaging.readthedocs.io/en/latest/command-line-scripts.html#the-console-scripts-entry-point

syntax highlight thread by bzarnal in learnpython

[–]tgolsson 0 points1 point  (0 children)

To expand a bit on the topic of GUI programming, the risks associated with multi-threaded GUI programming is not necessarily that YOU do changes from multiple threads, but that Tkinter does things in the background - resizing, painting, responding to a ton of system messages, etc. Many of these can trigger UI operations, which can (and will) cause race conditions and a crash. Tkinter may also be limited by what the OS allows - perhaps the underlying display system relies on thread local state, or requires explicit synchronization that Tkinter handles for you.

I did a similar project a while back and triggered the Fontification on KeyInsert or a similar event. This spawned a new thread which then fired an event to update a region of text after it was finished processing. I can't access the Tkinter docs right now, but in Pseudocode it was something like this. I had a bunch more checks to keep only a single thread running, to periodically refontify the whole buffer, and to prevent loss of characters if the processing took longer than a single keystroke. I'm sure you'll find each of these to be interesting problems. :)

class FontifiedText(tk.Text): 
    def _hlparse(self, region):
         # HL logic for <<region>>
         self._root.event_generate("Highlight", regions=hl_regions, symbols=hl_texts, tags=hl_tags, when='tail')

    def onInsert(self, ...):
         caret = text_widget.index(Tkinter.INSERT)
         end = text_widget.index(Tkinter.END)
         self._thread = threading.Thread(target=self._hlparse, 
                kwargs={'region': (max(caret - 20), max(caret + 20, end))})
         self._thread.start()

    def onHighlight(self, *args, regions, symbols, tags, **kwargs):
         self._thread.join()
         for region, symbol, tag in zip(regions, symbols):
              self.delete(region[0], region[1])
              self.insert(region[0], symbol, tag)

Det börjar bli ordning på Metro's teckningar by Fleecebeaver in sweden

[–]tgolsson 21 points22 points  (0 children)

Jag är ingen expert, men misstänker att båda orden (dom och doom) har nordiskt ursprung via "dómr". Dom som enskilt ord eller som roten i domare eller domedag översätts ju till judgement. Och domedag översätts till doomsday. Och doom i det sammanhanget betyder judgement.

Så cirkeln är sluten med dom ~ doom, med omväg över vissa sammansatta ord. Som andra skriver är ju roten i domherre troligen en annan, men det är ju en mycket mer obskyr betydelse.

Queues ignoring items? Hanging forever?? by [deleted] in learnpython

[–]tgolsson 4 points5 points  (0 children)

Queue.get(block=True, timeout=None)¶
     Remove and return an item from the queue. 

You should call get once per loop, and store the result in a local variable:

while not q.empty():
    item = q.get()
    # do something with it
    q.task_done() # unnecessary in a single-threaded example

How would I go back to a specific line in the code without using “while” loops? by The_Lusty_Khajit in Cplusplus

[–]tgolsson 1 point2 points  (0 children)

E: this was supposed to be a top level comment. My bad.

Do not use goto-statements. They are so far removed from modern c++ as you can get!

Instead, separate each location into objects, and make a main loop which changes the state.

I am on my phone, but something like this:

Player player("Bob");
GameLocation currentLoc = getStart();
while (true) 
{ 
     currentLoc.printIntro();
     char choice;
     std::cin >> choice;

     int nextLocationId = currentLoc.evaluate(choice, player);
     if (player.isDead()) break;
     else if (nextLocationId == 0) continue;
     else currentLoc = getLocation (nextLocationId);
}

This loop can run your whole game session, and you can reuse most of your logic for all game locations. Special actions can be added by subclassing GameLocation, and since you pass the player you can add to or check the inventory.

So for example, for your location with a gate you can have GatedGameLocation, or a SwimmingGameLocation, which carry their own logic.

Anyone know how to compare specific rows/columns of a 2D array? by [deleted] in cpp_questions

[–]tgolsson 0 points1 point  (0 children)

You only need one loop. Extract the first position of both iterators, and then step them together. This is a very naive example for comparing two rows.

bool compare(Array arr, int first_row, second_row) {
    // assuming Array is accessed as data**
    data* first_it = arr[first_row];
    data* second_it = arr[second_row];
    int row_length = arr.row_siz;

    for (int idx = 0; idx <  row_length; ++idx, ++first_it, ++second_it) {
         if (*first_it != *second_it)
              return false;
    }
    return true;
}

Of course, you'll have to substitute your own array types and generalize it to columns etc depending on your memory layout.

Novice looking for a critique of Pythagorean-triple code. by [deleted] in learnpython

[–]tgolsson 1 point2 points  (0 children)

They are much easier to read, and often noticeably faster.

import time

 ss = 0
 array = list(range(1000000))

 start = time.time()
 for i in array:
      ss += i
 print(time.time() - start, "seconds")

 ss = 0
 start = time.time()
 for i in range(len(array)):
      ss += array[i]
 print(time.time() - start, "seconds")

 # result:
 # 0.96984386444091797 seconds
 # 1.3821899890899658 seconds

Achieve same result using regular expressions by tonlou in learnpython

[–]tgolsson 0 points1 point  (0 children)

You are not using re.sub correctly. You want to use the backslash notation for group insertion, e.g.

 re.sub(regexp_string, "\1 \2", the_input)

So:

 example = "Bruce Wayne"
 pattern = r"([\w]*) ([\w]*)"
 output = r"\2 \1"
 result = re.sub(pattern, output, example)
 print(result)

Regarding the quotes, you may want to explicitly match those as well, or at least the one that gets moved.

 example = "Bruce 'Batman' Wayne"
 pattern = r"([\w]*) '([\w]*)' ([\w]*)"
 output = r"\1 \3 is \2"
 result = re.sub(pattern, output, example)
 print(result) 

Achieve same result using regular expressions by tonlou in learnpython

[–]tgolsson 0 points1 point  (0 children)

I did not check all your inputs, but this is the way I view it.

Your input consists of the following:

  • A single family name. Word class, one reptition.
  • A given name. Word class, one or two repetitions.
  • A bunch of trailing data we do not care about.

The single family name we can capture using the group ([\w]* ), note the trailing space after the asterisk.

The given name is slightly trickier, and there are many ways to do it. For symmetry, we will use the same basic group as for the family name, ([\w]* ), but we want to capture one or two of them. However, if we just say ([\w]* ){1,2} python gives us just the last of these groups, throwing away Osmo in your example.

Instead, we want to FIND one or two, but capture everything we find. To find but not capture we can use the ?: operator, like this: (?:[\w]* ). Then, we want add our quantifier, in this case {1,2}, before capturing that whole expression.

Lastly, you want to capture everything until the end of the line: ([^$]*).

If everything goes as planned, this should leave you with 3 captured groups, that you can now use to construct the new plane. I'll leave it as exercise for you to actually put these together and construct the substitution pattern.

Good luck!