Python Forum
mutable values to string items?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
mutable values to string items?
#1
Hi,
I've got the next list:
channels = [
    [ '#channel1', 0 ],
    [ '#channel2', 0 ],
    [ '#channel3', 0 ]
]
I can change the values for each channel like:
channel1[1] = somevalue
channel2[1] = somevalue
channel3[1] = anothervalue
That is working oke.
The problem is, the script is changed and now it uses a string like:
net.ipv6 "#channel1,#channel2,#channel3"
I can call each channel separtly by:
for channel in channels.split(',')
No problem for this part.
The big question is: How can i add the mutable values for each item (channel) in this string?
Reply
#2
Maybe a dictionary would work,but not sure what task you try to solve with it.
>>> ch = "#channel1,#channel2,#channel3"
>>> ch = ch.split(',')
>>> ch
['#channel1', '#channel2', '#channel3']

>>> values = (1, 42, 'spam')
>>> d = dict(zip(ch, values))
>>> d
{'#channel1': 1, '#channel2': 42, '#channel3': 'spam'}
>>> d['#channel2'] = 100
>>> d
{'#channel1': 1, '#channel2': 100, '#channel3': 'spam'}

>>> d.get('#channel3', 'No channel found')
'spam'
>>> d.get('#channel4', 'No channel found')
'No channel found'
fozz likes this post
Reply
#3
Does this do what you have in mind?

x = "#channel1,#channel2,#channel3"
x_list = []
x_string = ''

for item in x:
    x_string += item
    if item == ',':
        x_list.append(x_string)
        x_list.append(0)
        x_string = ''
x_list.append(x_string)
x_list.append(0)

print(x_list)
Output:
['#channel1,', 0, '#channel2,', 0, '#channel3', 0]
fozz likes this post
Sig:
>>> import this

The UNIX philosophy: "Do one thing, and do it well."

"The danger of computers becoming like humans is not as great as the danger of humans becoming like computers." :~ Konrad Zuse

"Everything should be made as simple as possible, but not simpler." :~ Albert Einstein
Reply
#4
I'm really confused because this:
channels = [
    [ '#channel1', 0 ],
    [ '#channel2', 0 ],
    [ '#channel3', 0 ]
Does not appear to have anything in common with this:
channel1[1] = somevalue
channel2[1] = somevalue
channel3[1] = anothervalue
What are you starting with, and how do you want it to look after it has been processed?
fozz likes this post
Reply
#5
(Aug-21-2022, 08:06 PM)fozz Wrote:
channels = [
    ['#channel1', 0],
    ['#channel2', 0],
    ['#channel3', 0],
]

Assigning the first element from channels to a name:
first = channels[0]
Assigning a list to the first element of the list channels:
channels[0] = ["channel33", 33]
If you do not want to use integer indices, then use a dict.
channels = {
    '#channel1': 0,
    '#channel2': 0,
    '#channel3': 0,
}

channels['#channel4'] = 33
channels['#channel1'] = 1

for name, value in channels.items():
    print(name, "->", value)
Output:
#channel1 -> 1 #channel2 -> 0 #channel3 -> 0 #channel4 -> 33
Getting all values, but not the channels (keys of the dict):
print(list(channels.values()))
Output:
[1, 0, 0, 33]
If you use for your program the wrong data structures, then handling the data is very complicated.
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#6
Thank you for the help guys, but like i said in the first post, that is the old situation, maybe I wasn't clear.
The goal is to make a channel limiter for irc channels (protection against mass joins) and make it work for more channels ,in the old script it worked flawless on multiple channels because of the list, in the new situation the script works, but only on one channel, if I add more then one channel in the string of the script the timer keeps on looping because the script cannot determine which value for what channel, so my idea was to add a value (the setted limit on the channel) to an item(channel) of the string.
Maybe it's better to post the old and new scripts to clarify it:
OLD situation:
from weechat import (
    WEECHAT_RC_OK, info_get, prnt, register, 
    string_eval_expression, command, hook_timer)

NAME = 'Limiter'
AUTHOR = 'fozz <fozz@someone>'
VERSION = '0.1'
LICENSE = 'GPL3'
DESCRIPTION = 'Channel limiter, protection against mass joining from clones/botnets'

register(NAME, AUTHOR, VERSION, LICENSE, DESCRIPTION, '', '')

# Configuration 
limit_ = 5
min_offset_ = 2 #lowest diff
max_offset_ = 2 #highest diff
interval_ = 3
network_ = 'ircnet'
channels_ = [
    [ '#python', 0 ],
    [ '#forum', 0 ]
]

def limiter_cb(data, signal):

    global limit_, min_offset_, max_offset_, network_, channels_

    for channel in channels_:
        
        buffer = info_get('irc_buffer', network_+',' + channel[0])
        nc = int(string_eval_expression('${buffer.nicklist_visible_count}', {'buffer': buffer}, {}, {}))
        nl = nc + limit_
        minoff = nl - min_offset_
        maxoff = nl + max_offset_

        if  channel[1] <= minoff or channel[1] >= maxoff:
            command(buffer, '/mode ' + channel[0] + ' +l ' + f'{nl}')
            channel[1] = nl

    return WEECHAT_RC_OK

hook_timer(interval_ * 60000, 0, 0, 'limiter_cb', '')
To be clear, the above script worked as it should (on multiple channels).
Now the new situation (is running also on more then one channel so that part is ok) but keeps on looping and setting the limit on the channel again and again (one channel added in the string is no problem)
# Simple Channel limiter version 0.1.
# Protection script against mass joining from clones/botnets on your channel.

''' /set plugins.var.python.limiter.limiter_chans.ircnet #python,#forum '''

from weechat import (
    WEECHAT_RC_OK, register, infolist_get, infolist_string, buffer_search,
    config_get_plugin, infolist_next, string_eval_expression, command, hook_timer, infolist_free)

NAME = 'limiter'
AUTHOR = 'fozz <[email protected]>'
VERSION = '0.1'
LICENSE = 'GPL3'
DESCRIPTION = 'Channel limiter, protection against mass joining from clones/botnets'

register(NAME, AUTHOR, VERSION, LICENSE, DESCRIPTION, '', '')

# Configuration 
limit_ = 5
min_offset_ = 2 #lowest diff
max_offset_ = 2 #highest diff
interval_ = 1

offset_ = int()

def limiter_cb(data, signal):

    global limit_, min_offset_, offset_, max_offset_

    networks = infolist_get('irc_server', '', '')
    while infolist_next(networks):
        network = infolist_string(networks, 'name')
        channels = config_get_plugin('limiter_chans.{}'.format(network))
        if channels:
            
            for channel in channels.split(','):
                buffer = buffer_search('irc', '{}.{}'.format(network, channel))
                if buffer:

                   nc = int(string_eval_expression('${buffer.nicklist_visible_count}', {'buffer': buffer}, {}, {}))
                   nl = nc + limit_ 
                   minoff = nl - min_offset_
                   maxoff = nl + max_offset_
                        
                   if  offset_ <= minoff or offset_ >= maxoff:
                       command(buffer, '/mode ' + channel + ' +l ' + f'{nl}')
                            
                       offset_ = nl

    infolist_free(networks)

    return WEECHAT_RC_OK

hook_timer(interval_ * 60000, 0, 0, 'limiter_cb', '')
Any help is very welcome, I stumbled upon setting the data for each channel separtly from the string to nest, that's why the idea with a list from the old situation or something.
The string is like this in the new situation:
limiter_chans.ircnet "#python,#forum"
Reply
#7
Any help please,
How can i write the channels found in the next string:
plugins.var.python.limiter.limiter_chans.ircnet #python,#forum
to a file (maybe using pandas or csv) and can read the data (the limit for the specific channel) back?
i can retrieve the setted channels with:
channels = config_get_plugin('limiter_chans.{}'.format(network))
The goal is that i don't have edit that file manually, so the only setting i change in the program is with:
/set plugins.var.python.limiter.limiter_chans.ircnet #python,#forum
It should look something like this in the file i guess
channels_ = [[ '#python', 0 ], [ '#forum', 0 ]]
Or:
channel | limit
#python | 45
#forum  | 64
(the #channels and llimits (45 and 64 in this example) should be modified by the script)
Reply
#8
Here is code to store the list in a csv file and read it back. Hope it helps
import csv
import io
from pathlib import Path

source = "plugins.var.python.limiter.limiter_chans.ircnet #python,#forum"

# extract the list ['#python', '#forum']
ichan = [x.strip() for x in source.split(' ', 1)[1].strip().split(',')]

# create the list [["#python#, 0], ['#forum', 0]]
channels = [[x, 0] for x in ichan]

# serialize channels as csv content
ofh = io.StringIO()
csv.writer(ofh).writerows(channels)
content = ofh.getvalue()

# optional: save content to file
filename = Path(__file__).parent/'channels.csv'
filename.write_text(content)

# optional: read file to get content
content = filename.read_text()

# deserialize content as a list of list
channels = [[chan, int(num)] for (chan, num) in csv.reader(io.StringIO(content))]
print(channels) # prints [['#python', 0], ['#forum', 0]]
fozz likes this post
Reply
#9
Why do you suddenly need a file? Before you had a list that contained this information. Why can't you still use a list (or a dictionary)?

What string are you talking about here?
Quote:The string is like this in the new situation:
limiter_chans.ircnet "#python,#forum"
What command in your program is returning this string? Or are you trying to generate a string like this? Assume that I know nothing about weechat. I think that is mostly true for most of the people on the forum. A search for weechat only found posts in this thread and your other thread "Matching multiple parts in string". No results at all for "wechat"
Reply
#10
Thank you for this Gribouillis, i will try that tomorrow.
Quote:Why do you suddenly need a file? Before you had a list that contained this information. Why can't you still use a list (or a dictionary)?
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  using mutable in function defintion as optional paramter akbarza 4 237 Yesterday, 12:52 PM
Last Post: deanhystad
  How to parse and group hierarchical list items from an unindented string in Python? ann23fr 0 205 Mar-27-2024, 01:16 PM
Last Post: ann23fr
  mutable argument in function definition akbarza 1 491 Dec-15-2023, 02:00 PM
Last Post: deanhystad
  Trying to compare string values in an if statement israelsattleen 1 565 Jul-08-2023, 03:49 PM
Last Post: deanhystad
  Getting rid of old string values Pedroski55 3 1,027 Oct-11-2022, 10:56 PM
Last Post: Pedroski55
  Parse String between 2 Delimiters and add as single list items lastyle 5 3,402 Apr-11-2021, 11:03 PM
Last Post: lastyle
  "'DataFrame' objects are mutable, thus they cannot be hashed" Mark17 1 6,841 Dec-25-2020, 02:31 AM
Last Post: tinh
  Mutable Strings millpond 3 2,575 Aug-24-2020, 08:42 AM
Last Post: millpond
  Function parameters and values as string infobound 1 1,770 Jul-24-2020, 04:28 AM
Last Post: scidam
  xml.etree.ElementTree extract string values matthias100 2 4,999 Jul-12-2020, 06:02 PM
Last Post: snippsat

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020