Save io.read() file reading result to a string - string

So I have some code:
io.input(file)
print(io.read())
result = io.read()
print(result)
io.close(file)
and when I run this, I get
dasdasd
nil
where "dasdasd" is the content of the file. This signifies to me that the result of io.read() was not properly not saved to the string. Why is this the case? What am I missing?

You're assuming read() goes back to the beginning each time. This would require a seek() operation to be performed. https://pgl.yoyo.org/luai/i/file%3Aseek
f = io .input( 'filename.txt' )
print( f :read() )
f :seek('set') -- set returns to the beginning
result = f :read()
print( result )
f :close()

Lua is not a referentially transparent programming language, and io.read() is not a pure function. If you want to use the output from a call to it multiple times, you can't just call it multiple times. Save it to a variable and use that instead (like you did anyway immediately after your first call to it).

Related

python's exec() works oddly inside functions

I (think I) need exec() to procedurally define variables for symbolic computation. The code searches for variables in an expression like 'x/y + z' and generates three variables,
x = sp.sympy('x'), y = sp.sympy('y'), z = sp.sympy('z')(for example).
When I run the code
for char in expr:
if char.isalpha():
exec('%s = sp.symbols("%s")' % (char, char))
print(type(char))
It works just as it should. print(type(char)) just checks if what I wanted to happen happens (it prints <class 'sympy.core.symbol.Symbol'> if it worked).
However, as I need this for a general expr, I need this inside a function. When I do this print(type(char)) outputs <class 'str'>, which means it didn't work.
Also, if I type print(type(char)) inside the exec I get a correct output.
Note: I know exec() is dangerous. I'm just going to use this to have an easier time writing lab reports.
I couldn't think of a way to get it into one line, but I believe this will work:
for char in expr:
if char.isalpha():
exec('%s = sp.symbols("%s")' % (char, char))
exec('temp_type = type(%s)' % char)
print(temp_type)
Alternatively using a dict approach may make it easier in the long run. It avoids the exec.
symbol_dict = dict()
for char in expr:
if char.isalpha():
symbol_dict[char] = sp.symbols(char)
print(symbol_dict[char])

How can a variable be assigned to two objects?

g = None
try:
g = open("mydata.txt", "r")
except IOError:
print(’Python could not open the file mydata.txt.’)
if g:
try:
lines = g.readlines()
print("The list of lines is:")
print(lines)
except IOError:
print(’Error while trying to read the data in the file.’)
This is an example of using try and except in python from my textbook. The textbook stated that "g is given an initial binding of None (which is treated as False within the boolean context of the if statement)". From my understanding, g already holds a file object returned from the open function, how can it be treated as False within the boolean context of the if statement?
g changes from holding a None to a File object when it's reassigned at:
g = open("mydata.txt", "r")
It doesn't "have 2 objects" at once.
It can't be both None and the contents of the file at the same time; the idea is that if open() fails, and the first Except block is hit, then g will still be equal toNone`.
So if the open() process completes successfully, than the if g statement will evaluate to true, and the function will proceed. If the open() process fails, g will still be equal to None, and therefore the if g statement will evaluate to false and the readlines() section will be skipped.
so it is important to understand that Python is an interpreted language which is executed statement by statement
when this code is compiled the compiler know that g is None from g = None. but the compiler keeps reading more lines. When it reads g = open("mydata.txt", "r") then the variable g now reassign to holds a file object and no longer none

string.gsub return as a distinct variable for each replace result

Input:
stringdata = '{"abcd://ipaddress/directory1/Images/subfolder/Image0.png","abcd://ipaddress/directory1/Images/subfolder/Image1.png","abcd://ipaddress/directory1/Images/subfolder/Image2.png","abcd://ipaddress/directory1/Images/subfolder/Image3.png","abcd://ipaddress/directory1/Images/subfolder/Image4.png"}'
Source Code
string.gsub(stringdata, "(.....................%w%w................................%w)",print)
Current output:
abcd://ipaddress/directory1/Images/subfolder/Image0.png
abcd://ipaddress/directory1/Images/subfolder/Image1.png
abcd://ipaddress/directory1/Images/subfolder/Image2.png
abcd://ipaddress/directory1/Images/subfolder/Image3.png
abcd://ipaddress/directory1/Images/subfolder/Image4.png
Expected output (where each of the below could be stored in a different variable)
directory1/Images/subfolder/Image0.png
directory1/Images/subfolder/Image1.png
directory1/Images/subfolder/Image2.png
directory1/Images/subfolder/Image3.png
directory1/Images/subfolder/Image4.png
With so many . in your pattern, it's hard to read and unclear what's your purpose.
Instead, use a pattern that's specific to the format:
string.gsub(stringdata, "%w+://%w+/(%w+/%w+/%w+/%w+%.png)", print)
In this way, it's much more clear what each %w+ represents.
To store the result, you are using the wrong function. string.gsub is used for substitution, use string.gmatch instead:
for m in string.gmatch(stringdata, "%w+://%w+/(%w+/%w+/%w+/%w+%.png)") do
print(m)
-- do whatever with m
end

Using Netwire to spawn lists from a value

I think I'm fundamentally misunderstanding how to attack this type of problem with Netwire:
I have the following test-case:
I'd like to take a string, split it into lines, print each line, then exit.
The pieces I'm missing are:
How to inhibit after a value early in a pipeline, but then if that value is split and the results produced later, not inhibit until all those results are consumed.
What the main loop function should look like
If I should use 'once'
Here is the code I have so far:
import Control.Wire
main :: IO ()
main = recur mainWire
recur :: Wire () IO () () -> IO ()
recur a = do
(e,w) <- stepWire a 0 ()
case e of Left () -> return ()
Right () -> recur w
mainWire :: Wire () IO () ()
mainWire = pure "asdf\nqwer\nzxcv"
>>> once
>>> arr lines
>>> fifo
>>> arr print
>>> perform
This outputs the following:
"asdf"
and then quits. If I remove the once, then the program performs as expected, repeatedly outputting the full list of lines forever.
I'd like the following output:
"asdf"
"qwer"
"zxcv"
I'm sure that I'm just missing some intuition here about the correct way to approach this class of problem with Netwire.
Note: This is for an older version of netwire (before events worked like they do now), so some translating of the code would be required to make this work properly with the current version.
If I understood you right, you want a wire that produces the lines of a string, and then inhibits when it's done with that? It's a bit hard to tell.
once as the name implies, produces exactly once and then inhibits forever. Again it's a bit unclear what your wires are doing (because you didn't tell us) but it's not something you normally put into your "main" wire (so far I've only ever used once with andThen).
If that is correct, I'd probably do it something along the lines of:
produceLines s = produceLines' $ lines s where
produceLines' [] = inhibit mempty
produceLines' (l:ls) = pure s . once --> produceLines' ls
(You could write that as a fold or something, I just thought this was a bit clearer).
--> is pretty for andThen in case you didn't know. Basically this splits the passed string into lines, and turns them into a wire that produces the first line once, and then behaves like a similar wire except with the first element removed. It inhibits indefinitely once all values were produced.
Is that what you wanted?
Update
I see what you were trying to do now.
The wire you were trying to write could be done as
perform . arr print . fifo . ((arr lines . pure "asdf\nqwer\nzxcv" . once) --> pure [])
The part in the parentheses produce ["adf","nqwer","nzxc"] for one instant, and then produces [] forever. fifo takes values from the previous wire, adding the result from the previous wire in every instance (because of that we have to keep producing []). The rest is as you know it (I'm using the function-like notation rather than the arrow notation because I prefer it, but that shouldn't be a problem for you).

Why doesn't this simple Lua coroutine work?

I have a very simple little piece of Lua code, which I wrote while teaching myself how coroutines work.
I was fine until I got to coroutine.wrap, the spec states:
coroutine.wrap (f)
Creates a new coroutine, with body f.
f must be a Lua function. Returns a
function that resumes the coroutine
each time it is called. Any arguments
passed to the function behave as the
extra arguments to resume. Returns the
same values returned by resume, except
the first boolean. In case of error,
propagates the error.
However this code:
Enumeration = {}
Enumeration.Create = function(generator)
return coroutine.wrap(generator, coroutine.yield)
end
local function TestEnumerator(yield)
yield(1) --ERROR HERE
yield(2)
yield(3)
end
local enumerator = Enumeration.Create(TestEnumerator)
local first = enumerator()
local second = enumerator()
local third = enumerator()
print (first, second, third)
Complains that yield is nil (on the line I have marked above). As I understand it, yield should be the second argument passed into coroutine.wrap, so where am I going wrong?
Really obvious solution, thanks to the answer below
Enumeration.Create = function(generator)
local iter = coroutine.wrap(generator, coroutine.yield)
return function()
return iter(coroutine.yield)
end
end
This is not how coroutine.wrap works. You have to pass coroutine.yield in the first call to enumerator.

Resources